SRM 492 DIV1 Medium TimeTravellingTour
http://apps.topcoder.com/stat?c=problem_statement&pm=10782&rd=14245
解答
この中の時間を基準に考えたら、時間の分岐が木になることがわかった。分岐がタイムトラベルポイントで、葉が訪れる街。
その木を左右に分割して探索していく。
この解法はO(n^5)だが、いくらかの定数倍速いのでぎりぎり間に合う。O(n^4)解法もあるらしい
コメント
DIV1 Medium自分で解けた!しかも結構難しい問題だったらしい。気持ちがいい!
実際に本番でやることになっていた場合、Easyとあわせてギリギリ間に合う程度の時間でできたらしい。もう少し早く解けるほうがいいね。
今はEasy半分より大きい程度の割合で解ける程度の感じだけど、このくらいをある程度解けるようになりたいねー
コード
#include <string> #include <vector> #include <algorithm> #include <set> #include <map> #include <queue> #include <iostream> #include <sstream> #include <cstdio> #include <cmath> #include <ctime> #include <cstring> #define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i)) #define rer(i,l,u) for(int (i)=(int)(l);(i)<=(int)(u);++(i)) #define reu(i,l,u) for(int (i)=(int)(l);(i)<(int)(u);++(i)) #define aut(v, x) __typeof(x) v = (x) #define each(it,o) for(aut(it, (o).begin()); it != (o).end(); ++ it) #define all(o) (o).begin(), (o).end() #define pb(x) push_back(x) #define mp(x,y) make_pair((x),(y)) #define mset(m,v) memset(m,v,sizeof(m)) using namespace std; typedef long long ll; typedef vector<int> vi; typedef pair<int,int> pii; typedef vector<pii> vpii; const int INF = 0x3f3f3f3f; const ll INFL = 0x3f3f3f3f3f3f3f3fLL; ll d[55][55]; ll dp[55][55][55]; struct TimeTravellingTour { vi t; int N; ll rec(int i, int l, int u) { if(dp[i][l][u]!=-1)return dp[i][l][u]; ll r = INFL; if(l == u) { r = d[i][t[l]]; }else { rep(k, N) if(d[i][k]!=INFL) { reu(s, l, u) { ll x = d[i][k], y; y = rec(k, l, s); if(y == INFL) continue; x += y; y = rec(k, s+1, u); if(y == INFL) continue; x += y; r = min(r, x); } } } return dp[i][l][u] = r; } long long determineCost(int N_, vector <int> t_, vector <string> roads) { N = N_; t = t_; string rs; each(i,roads)rs+=*i; each(i,rs)if(*i==',')*i=' '; stringstream s(rs); int a,b,c; mset(d, (unsigned char)INFL); rep(i, N) d[i][i] = 0; while(s >> a >> b >> c) { d[a][b] = min(d[a][b], (ll)c); d[b][a] = min(d[b][a], (ll)c); } rep(k, N) rep(i, N) rep(j, N) { if(d[i][k] != INFL && d[k][j] != INFL) d[i][j] = min(d[i][j], d[i][k] + d[k][j]); } mset(dp, -1); ll r = rec(0, 0, t.size()-1); return r == INFL ? -1 : r; } };