动态规划特训:城市里的间谍(UVA1025)多状态转移

解题思路:分析可知,到达某一站有三种选择,转换至另外三个状态,分别是选择等待,登上向右开的列车(如果有),登上向左开的列车(如果有),因为只有花费时间和站台位置影响最终结果(最少等待的时间),故设置二维数组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;
}

猜你喜欢

转载自blog.csdn.net/mavises/article/details/82012965
今日推荐