题意:总共有n个车站,一个特务开始的时候在1车站,他需要在T时刻到达n车站会见一个人,如果他在车站停留的时间越长,那么他被发现的几率就越大
电车从i到i+1车站的时间为ti,然后又m1辆车在1车站往n车站走,分别给出这m1辆车从1车站出发的时间,有m2辆车从n车站往1车站走,该特务的身手敏捷,如果在某一个时刻有车发车,他可以迅速上车,即使当时他在另一个车上
分析:表示特务的状态需要两个量,时间和车站,dp[i][j]表示i时刻在j车站,从这个状态到达dp[T][n]这个状态需要的最少时间
那么我们在每一个状态都有三种决策:
1.在该车站停留1分钟
2.坐车往左走
3.坐车往右走
提前打出i时刻j车站能否往左右走的表
#include<bits/stdc++.h> using namespace std; const int maxn=55; const int maxt=205; const int INF=0x3f3f3f3f; int n,T,cas=1; int v[maxt][maxn][2],dp[maxt][maxn],t[maxn]; bool read(){ scanf("%d",&n); if(!n) return false; scanf("%d",&T); for(int i=1;i<n;i++) scanf("%d",t+i); int m,temp; memset(v,0,sizeof(v)); scanf("%d",&m); for(int i=1;i<=m;i++){ scanf("%d",&temp); v[temp][1][0]=1; for(int j=1;j<n;j++){ temp+=t[j]; if(temp<=T) v[temp][j+1][0]=1; else break; } } scanf("%d",&m); for(int i=1;i<=m;i++){ scanf("%d",&temp); v[temp][n][1]=1; for(int j=n-1;j>1;j--){ temp+=t[j]; if(temp<=T) v[temp][j][1]=1; else break; } } return true; } void solve(){ for(int i=1;i<n;i++) dp[T][i]=INF; dp[T][n]=0; for(int i=T-1;i>=0;i--) for(int j=1;j<=n;j++){ dp[i][j]=dp[i+1][j]+1; if(j<n&&v[i][j][0]&&i+t[j]<=T) dp[i][j]=min(dp[i][j],dp[i+t[j]][j+1]); if(j>1&&v[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: impossible ",cas++); else printf("Case Number %d: %d ",cas++,dp[0][1]); } int main(){ while(read()) solve(); return 0; }