这道题的边界是dp(T,N)=0,状态dp(i,j)表示在时间i、第j个车站最少等待时间,有三个决策:1、等1分钟 2、如果有向左的车,向左 3、若果有向右的车,向右 转移方程就是dp(i,j)=min(dp(i+1,j),dp(i+t[j],j+1),dp(i+t[j-1],j-1))
AC代码:
#include若有不当之处欢迎指出!#include #include using namespace std;const int INF=1<<30;const int maxn=200+5;int dp[maxn][55];int time[55],t[55];int has[12600][55][2]; //has trainint main(){ int N,T,M1,M2; int kase=0; while(scanf("%d",&N)==1&&N){ scanf("%d",&T); time[1]=0; for(int i=2;i<=N;++i){ scanf("%d",&t[i]); time[i]=time[i-1]+t[i]; } memset(has,0,sizeof(has)); scanf("%d",&M1); for(int i=1;i<=M1;++i){ //right int r; scanf("%d",&r); for(int j=1;j<=N;++j){ has[r+time[j]][j][0]=1; } } scanf("%d",&M2); for(int i=1;i<=M2;++i){ int l; scanf("%d",&l); for(int j=N;j>=1;--j){ has[l+time[N]-time[j]][j][1]=1; } } for(int i=1;i =0;--i) for(int j=1;j<=N;++j){ dp[i][j]=dp[i+1][j]+1; if(j <=T) dp[i][j]=min(dp[i][j],dp[i+t[j+1]][j+1]); if(j>1&&has[i][j][1]&&i+t[j]<=T) dp[i][j]=min(dp[i][j],dp[i+t[j]][j-1]); } printf("Case Number %d: ",++kase); if(dp[0][1]>=INF) printf("impossible\n"); else printf("%d\n",dp[0][1]); } return 0;}