動態規劃——A Spy in the Metro UVA - 1025
阿新 • • 發佈:2018-11-09
題解:
這道題目基本上是線性dp,,只需要在記率每個時刻,每個車站左邊或者右邊有木有車駛來,
一共有三種狀態(等待,上左車,上右車),就可以判斷下一狀態需要等待的時間了,具體解法紫書上有說明
注意點:需要注意你儲存每一站的時間的下標是怎樣的,然後根據你的下標在你記錄車輛的時候注意下標,dp的時候也要注意下標
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int inf = 0x3f3f3f3f; int n,t; //車站數和約定的時間 int tim[55]; //每個車站的行走時間 int m1,m2; int hav_train[300][55][2]; //某個時間點某個車站某個方向有木有車 int dp[255][55]; //某個時間某個車站的已經等待時間 void add_train(int tt, int f) { //某個時間某個方向發車 if(!f) { hav_train[tt][1][0] = 1; //f為0車站從右邊出發 for(int i = 1; i < n-1; i++) { tt = tt+tim[i]; if(tt > 200) break; //已經超過約定的最大時間 hav_train[tt][i+1][0] = 1; //f為0車站從右邊出發 } } else { hav_train[tt][n][1] = 1; for(int i = n-1; i > 1; i--) { tt = tt+tim[i]; if(tt > 200) break; //已經超過約定的最大時間 hav_train[tt][i][1] = 1; //f為0車站從右邊出發 } } } int main() { //freopen("in.txt","r",stdin); int rnd = 0; while(scanf("%d",&n) == 1 && n) { memset(hav_train,0,sizeof(hav_train)); scanf("%d",&t); for(int i = 1; i <= n-1; i++) //只有n-1個間隔 scanf("%d",&tim[i]); //1代表1-2的時間 int tmp; scanf("%d",&m1); for(int i = 0; i < m1; i++) { scanf("%d",&tmp); add_train(tmp,0); } scanf("%d",&m2); for(int i = 0; i < m2; i++) { scanf("%d",&tmp); add_train(tmp,1); } memset(dp,inf,sizeof(dp)); dp[0][1] = 0; //0時刻第一個車站等待時間為0 for(int i = 0; i <= t; i++) { //遍歷每個時間和車站 for(int j = 1; j <= n; j++) { dp[i+1][j] = min(dp[i+1][j],dp[i][j]+1); if(hav_train[i][j][0]) dp[i+tim[j]][j+1] = min(dp[i+tim[j]][j+1],dp[i][j]); if(hav_train[i][j][1]) dp[i+tim[j-1]][j-1] = min(dp[i+tim[j-1]][j-1],dp[i][j]); } } if(dp[t][n] < inf) printf("Case Number %d: %d\n",++rnd,dp[t][n]); else printf("Case Number %d: impossible\n",++rnd); } return 0; }