A Spy in the Metro UVA - 1025
本文参考刘汝佳《算法竞赛入门经典》(第2版)
* 动态规划的核心是状态和状态转移方程*
/*
【理解题意】
注意本题要求的是最短的等待时间!就是在各个车站等待的时间之和的最小值!
建议通过输入输出样例来更好的明白题意!要尽量多在车上待着,减少在车站等
的时间,这样安全乎!并且要保证在T时刻(约会时间)到达终点。
【动态规划】
要注意时间这个天然的顺序!她总是在均匀的不停的流淌着……
状态:d(i,j)表示i时刻,在j车站至少要等待的时间
状态转移:在某个车站,
1)继续等待:d(i,j)=d(i+1,j)+1
2)坐左边来的车:d(i,j)=min{d(i+t[j],j+1) | j<n,i+t[j]<=T}
3)坐右边来的车:d(i,j)=min{d(i+t[j-1],j-1) | j>1,i+t[j-1]<=T}
*/
#include<iostream>
#include<cstring>
using namespace std;
const int INF=200;//题目给出的T最大值是200,大于200不可能约会成功
int N,T,t[100],M1,d_L[100],M2,d_R[100];
int dp[300][100];
int kase=0;//打印要求打印编号
//has_train[300][100][0],has_train[300][100][1]分别标记左边和右边在i时刻,j车站是否有车
bool has_train[300][100][2];
int main()
{
while(cin>>N && N){
memset(has_train,false,sizeof(has_train));
cin>>T;
for(int i=1;i<N;i++){
cin>>t[i];
}
cin>>M1;
for(int i=0;i<M1;i++){
cin>>d_L[i];
int time=d_L[i];
has_train[time][1][0]=true;
for(int j=1;j<N;j++){
time+=t[j];
has_train[time][j+1][0]=true;
}
}
cin>>M2;
for(int i=0;i<M2;i++){
cin>>d_R[i];
int time=d_R[i];
has_train[time][N][1]=true;
for(int j=N;j>1;j--){
time+=t[j-1];
has_train[time][j-1][1]=true;
}
}
//这里只初始化最后一行,从后向前递推即可
dp[T][N]=0;
for(int i=1;i<N;i++){
dp[T][i]=INF;
}
for(int i=T-1;i>=0;i--){
for(int j=1;j<=N;j++){
dp[i][j]=dp[i+1][j]+1;
if(i+t[j]<=T && j<N && has_train[i][j][0]){
dp[i][j]=min(dp[i][j],dp[i+t[j]][j+1]);
}
if(i+t[j-1]<=T && j>1 && has_train[i][j][1]){
dp[i][j]=min(dp[i][j],dp[i+t[j-1]][j-1]);
}
}
}
cout<<"Case Number "<<++kase<<": ";
if(dp[0][1]>=INF){
cout<<"impossible"<<endl;
}else{
cout<<dp[0][1]<<endl;
}
}
return 0;
}
【本题注意】
要注意开数组开的稍微大一点,如果开的稍微小一点的话,可能过不了!!!