解题思路:分析可知,到达某一站有三种选择,转换至另外三个状态,分别是选择等待,登上向右开的列车(如果有),登上向左开的列车(如果有),因为只有花费时间和站台位置影响最终结果(最少等待的时间),故设置二维数组dp[i][j]表示某状态下花费的最小等待时间,其中i表示总时间,j表示到达站台位置,。边界条件是状态dp[T][N]=0,和dp[T][i]=inf,即在T时刻到达车站N为需要的终止状态,在该状态下最小等待时间为0,其余时间为T的状态不是我们需要的状态,故设置为inf,在递推比较时会被抛弃。可以参考代码注释。
题目描述:本题大概意思是从车站1出发,在T时刻到达车站n,列车从某一站到后一站时间固定(倒过来花费时间相同)。两个方向皆有一定数量的列车,数量及出发时间输入给定,当方向相反的列车到达同一站可以立刻换乘(不需要等待),若选择到达某一站后不上车,或无车可上,选择等待,则会耗时1秒。问从车站1出发,t时刻到达车站n花在等待上的时间是多少。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define inf 1<<30
int n,t,statime[71],m1,m2,froml[51],fromr[51],have_train[201][51][2];
int dp[201][51];
int main()
{
while(cin>>n>>t)
{
memset(have_train,0,sizeof(have_train));
for(int i=1;i<=n-1;i++)
{
cin>>statime[i];
}
cin>>m1;
for(int i=1;i<=m1;i++)
{
cin>>froml[i];
}
cin>>m2;
for(int i=1;i<=m2;i++)
{
cin>>fromr[i];
}
for(int i=1;i<=m1;i++)
{
int tmpt=0;
for(int j=0;j<=n-1;j++)
{
tmpt+=statime[j];
have_train[froml[i]+tmpt][j+1][0]=1; //从左出发的列车某时刻到达某站,即该状态可以乘车置1
}
}
for(int i=0;i<=m2;i++)
{
int tmpt=0;
for(int j=n;j>=1;j--)
{
tmpt+=statime[j];
have_train[fromr[i]+tmpt][j][1]=1; //从右出发的列车某时刻到达某站,即该状态可以乘车置1
}
}
for(int i=1;i<=n;i++) //设置为inf表示该终止状态非所需,让其在比较过程中被丢弃
{
dp[t][i]=inf;
}
dp[t][n]=0;
for(int i=t;i>=0;i--)
{
for(int j=1;j<=n;j++)
{ //取3种状态中耗时最少的
if(i+1<=t)
dp[i][j]=dp[i+1][j]+1;
if(have_train[i][j][0]&&j<n&&i+statime[j]<=t) //注意比较状态的前提条件,防止数组越界
{
dp[i][j]=min(dp[i][j],dp[i+statime[j]][j+1]);
}
if(have_train[i][j][1]&&j>1&&i+statime[j-1]<=t)
{
dp[i][j]=min(dp[i][j],dp[i+statime[j-1]][j-1]);
}
}
}
if(dp[0][1]<=t)
cout<<dp[0][1]<<endl;
else
cout<<"impossible"<<endl;
}
return 0;
}