题意:一人要从一号车站做车去n号车站,输入每两个车站间的通过时间,和两头火车的出发时间,求这个人最少要在车站等多久;
思路:动态规划,仅考虑当前时间和所在车站对结果的影响,dp【T】【i】 表示最少还需要等待多长时间;
#include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int maxn = 55; const int INF = 0x3f3f3f; int n,T; int t[maxn]; int m1,m2; int train0[55],train1[55],has_train[205][55][2]; int dp[205][55]; int main(){ int kase=0; while(~scanf("%d",&n)) { memset(has_train,0,sizeof(has_train)); memset(dp,0,sizeof(dp)); if(n==0)break; scanf("%d",&T); for(int i = 1; i <= n-1; i++) scanf("%d",&t[i]); scanf("%d",&m1); for(int i = 1; i <= m1; i++)scanf("%d",&train0[i]); scanf("%d",&m2); for(int i = 1; i <= m2; i++)scanf("%d",&train1[i]); for(int i = 1; i <= m1; i++) { int tmp = train0[i]; int id = 1; while(tmp <= T) { has_train[tmp][id][0]=1; tmp+=t[id]; id++; if(id>=n)break; } } for(int i = 1; i <= m2; i++) { int tmp = train1[i]; int id = n; //一开始这里写成n-1一直wa; while(tmp <= T) { has_train[tmp][id][1]=1; tmp+=t[id-1]; id--; if(id<=1)break; } } for(int i=1;i<=n-1;i++) dp[T][i] = INF; dp[T][n] = 0; for(int i = T-1; i>=0; i--) //dp核心! { for(int j=1 ;j<=n;j++) { dp[i][j]=dp[i+1][j]+1; //相当于在车站等一分钟; if(j<n&&has_train[i][j][0]&&i+t[j]<=T) //has_train[][]表示第i秒在第j个车站是否有火车经过,有->把这个车站的等待时间接到前一个; dp[i][j]=min(dp[i][j],dp[i+t[j]][j+1]);//注意在车站是不耗时间的//相当于向右走 if(j>1&&has_train[i][j][1]&&i+t[j-1]<=T) //相当于向左走; dp[i][j]=min(dp[i][j],dp[i+t[j-1]][j-1]); } } if(dp[0][1]<INF) printf("Case Number %d: %d\n",++kase,dp[0][1]); else printf("Case Number %d: impossible\n",++kase); } return 0; }