UVA1025 城市里的间谍 A Spy in the Metro

参照《算法竞赛入门经典(第二版)》,这上面写得很清楚。

核心代码如下:

for(int tim=t-1;tim>=0;tim--)
	for(int sta=1;sta<=n;sta++){
		dp[tim][sta]=dp[tim+1][sta]+1;
		if(sta<n&&lt[sta][tim]&&tim+a[sta]<=t)
			dp[tim][sta]=min(dp[tim][sta],dp[tim+a[sta]][sta+1]);
		if(sta>1&&rt[sta][tim]&&tim+a[sta-1]<=t)
		dp[tim][sta]=min(dp[tim][sta],dp[tim+a[sta-1]][sta-1]);
	}

全部代码如下:

#include<bits/stdc++.h>
using namespace std;
#define inf 1e9
const int maxn=55;
const int maxt=205;
int n,t,a[maxn],l,r,x,kase;
int lsum[maxn],rsum[maxn];
int lt[maxn][maxt],rt[maxn][maxt];
int dp[maxt][maxn];
int main(){
	while(1){
		cin>>n;
		if(!n)return 0;
		cin>>t;
		for(int i=1;i<n;i++)
			scanf("%d",&a[i]);
		for(int i=1;i<=n;i++)
			lsum[i]=rsum[i]=0;
		for(int i=2;i<=n;i++)
			lsum[i]=lsum[i-1]+a[i-1];
		for(int i=n-1;i>=1;i--)
			rsum[i]=rsum[i+1]+a[i];
		cin>>l;
		memset(lt,0,sizeof(lt));
		for(int i=1;i<=l;i++){
			cin>>x;
			for(int j=1;j<n&&x+lsum[j]<=t;j++)
				lt[j][x+lsum[j]]=1;
		}
		cin>>r;
		memset(rt,0,sizeof(rt));
		for(int i=1;i<=r;i++){
			cin>>x;
			for(int j=n;j>1&&x+rsum[j]<=t;j--)
				rt[j][x+rsum[j]]=1;
		}
		for(int i=0;i<=t;i++)
			for(int j=1;j<=n;j++)
				dp[i][j]=inf;
		dp[t][n]=0;
		for(int tim=t-1;tim>=0;tim--)
			for(int sta=1;sta<=n;sta++){
				dp[tim][sta]=dp[tim+1][sta]+1;
				if(sta<n&&lt[sta][tim]&&tim+a[sta]<=t)
					dp[tim][sta]=min(dp[tim][sta],dp[tim+a[sta]][sta+1]);
				if(sta>1&&rt[sta][tim]&&tim+a[sta-1]<=t)
					dp[tim][sta]=min(dp[tim][sta],dp[tim+a[sta-1]][sta-1]);
			}
		cout<<"Case Number "<<++kase<<": ";
		if(dp[0][1]>=inf)puts("impossible");
		else printf("%d\n",dp[0][1]);
	}
	return 0;
}

倒推十分巧妙。

posted @ 2020-05-24 16:01  syzf2222  阅读(104)  评论(0编辑  收藏  举报