第一道动态规划。。书中给的状态转移的设计感觉很巧妙
要注意下数组大小避免RE。
Run Time: 0.032s
#define UVa "LT9-1.1025.cpp" //A Spy in the Metro char fileIn[30] = UVa, fileOut[30] = UVa; #include<cstring> #include<cstdio> #include<algorithm> using namespace std; //Global Variables. Reset upon Each Case! const int maxt = 4000 + 10, maxn = 50 + 10, maxm = 50 + 10, INF = 100000000; int N, T, M1, M2, t[maxn], d[maxm], e[maxm]; int has_train[maxt][maxn][2]; int dp[maxt][maxn]; ///// void init() { memset(has_train, 0, sizeof(has_train)); scanf("%d", &T); for(int i = 0; i < N-1; i ++) scanf("%d", &t[i]); scanf("%d", &M1); for(int i = 0; i < M1; i ++) scanf("%d", &d[i]); scanf("%d", &M2); for(int i = 0; i < M2; i ++) scanf("%d", &e[i]); for(int i = 0; i < M1; i ++) { //trains from left start point. int time = d[i]; has_train[time][0][0] = 1; for(int j = 0; j < N-1; j ++) { //N-1 stations, N-2 intervals. time += t[j]; has_train[time][j+1][0] = 1; } } for(int i = 0; i < M2; i ++) { //trains from right start point. int time = e[i]; has_train[time][N-1][1] = 1; for(int j = N-2; j >= 0; j --) { //N-1 stations, N-2 intervals. time += t[j]; has_train[time][j][1] = 1; } } } int main() { int kase = 0; while(scanf("%d", &N) && N) { init(); for(int i = 0; i < N; i ++) dp[T][i] = INF; for(int i = 0; i <= T; i ++) dp[i][N-1] = 0; for(int i = T - 1; i >= 0; i --) { for(int j = 0; j < N; j ++) { dp[i][j] = dp[i+1][j] + 1; if(has_train[i][j][0] && j < N-1 && i + t[j] <= T) dp[i][j] = min(dp[i][j], dp[i+t[j]][j+1]); if(has_train[i][j][1] && j > 0 && i + t[j-1] <= T) dp[i][j] = min(dp[i][j], dp[i+t[j-1]][j-1]); } } printf("Case Number %d: ", ++kase); if(dp[0][0] >= INF) printf("impossible\n"); else printf("%d\n", dp[0][0]); } return 0; }