TopCoder SRM471 Div1(ノーコンテスト)

24:00開始だとちょっと眠くなる。

Result

No Contest.


良かったのか悪かったのかw
多分2問通ってたろうからレートは上がってたと思うけど。


……Practice Roomで500も通った。ちょっと勿体無いなw

Easy PrimeSequences

問題

素数のうち、2で割った(余りは切り捨てる)商がまた素数になるものがある。(7->3など)
ある数が素数でなくなるまで2で割り続けて列を作るとき、この列の長さを「数Xに対する列の長さ」と呼ぶことにする。(23->11->5->2なら長さ4)


N以下の整数で、列の長さがD以上になるような数のうち最も大きいものを返せ。
そのような数が存在しないときは-1を返せ。
2≦N≦1000万
1≦D≦10とする。

試行錯誤

問題文読解に手間取る。うーん?列の長さがD以上で最大になるような数を求めよってことか?
サンプルもそんな感じっぽい。


書いてみる。列の長さを求める関数は適当にメモ化。
あれ?最後のサンプル合わないぞ。もう一回問題文を読み直そう。


どうも単に列の長さがD以上になる数らしい。見つけたらすぐにループを抜けるよう変更。おkサンプルあった。最大ケースも余裕だよね送信。


最大ケー……ス100万じゃなくて1000万じゃねーか!!ばか!!
リサブミット。しぬる。200点は確保できたのでそこまで痛手ではないはず。

Medium ThirteenHard

問題

N個の都市があり、各都市間の距離が隣接行列の形で与えられるとき、以下の条件を満たしながら都市0から都市N-1に移動するときの最短時間を求めよ。
移動が不可能なときは-1を返せ。

  • 各移動にかかる時間をT[0],T[1],...,T[m]とすると、すべての0≦i≦j≦mなるi,jに対してT[i]+T[i+1]+...+T[j]が13の倍数にならない。

ただし、N≦25とする。

試行錯誤

今までの経路の長さを持ちながら探索だと思うけど、それらはmod 13でだけ考えればよい。
となると13!以下ぐらいにはなるのか?ん、いや違う。
新しい移動をi+1回目とすると、今までの区間の移動が合法なら、調べるのは

  • T[i+1]
  • T[i]+T[i+1]
  • T[i-1]+T[i]+T[i+1]

……

  • T[0]+T[1]+...+T[i+1]だけでよい。

↑そして、上の値を記憶しておく。

ということは経路のなかに0-12が出現したかどうかだけ覚えればいいからビットDP(ダイクストラ)になるのか。面白いなー。


書いた。全然値が合わない。
経路の合法性判定間違ってたのを探し出すのに20分くらいかかった。


提出しようと思ったらサーバが落ちて終了。
ラクティスで提出したら通ってたよ!100位くらいにはなってたんじゃないか?勿体無いね!

ソースコード
int dp[25][1<<13];

class ThirteenHard {
	public:
	int D(char c)
	{
		if('A'<=c&&c<='Z')return c-'A'+1;
		return c-'a'+27;
	}
	
	int calcTime(vector <string> city) 
	{
		int n=city.size();
		rep(i,n)rep(j,1<<13)dp[i][j]=inf;
		
		dp[0][0]=0;
		priority_queue<pair<int,pi> > Q; Q.push(mp(0,mp(0,0)));
		
		while(!Q.empty())
		{
			int cc=Q.top().first;
			int cur=Q.top().second.first,bit=Q.top().second.second;
			Q.pop();
			
			if(cur==n-1)break;
			
			rep(i,n)if(city[cur][i]!='#')
			{
				int d=D(city[cur][i]),nbit=1<<d%13,nc=cc-d;
				if(d%13==0)goto FAIL;
				
				//bit ck
				rep(j,13)if(bit&1<<j)
				{
					if((j+d)%13==0)goto FAIL;
				}
				
				rep(j,13)if(bit&1<<j)
				{
					nbit|=1<<(j+d)%13;
				}
				
				if(dp[i][nbit]<=-nc)goto FAIL;
				dp[i][nbit]=-nc;
				Q.push(mp(nc,mp(i,nbit)));
				
				FAIL:;
			}
		}
		
		
		int ans=inf;
		rep(i,1<<13)ans=min(ans,dp[n-1][i]);
		return ans==inf?-1:ans;
	}
};