紫书 UVa1025城市里的间谍

题目链接:UVa1025城市里的间谍

题解:

这种线段决策问题不难解,只要保存号当时某个时刻某个车站有木有车到来,然后就分为三种决策,不上车,上左车,上右车

代码如下

#include <bits/stdc++.h>
using namespace std;

int N,T,M1,M2;
int jian[55];
int hav_train[300][55][2]; //第i时刻第j个站,0为左来车,1为右来车
int dp[300][55];	//第i秒的时候在几个车站

void in_train(int time, int x) {	//出发时间和车的方向
	if(x) {	//右车
		hav_train[time][N][x] = 1;
		for(int i = N-1; i >= 0; i--) {
			time += jian[i];
			if(time > 250) break;
			hav_train[time][i][x] = 1;
		}
	} else {	//左车
		hav_train[time][1][x] = 1;
		for(int i = 1; i < N; i++) {
			time += jian[i];
			if(time > 250) break;
			hav_train[time][i+1][x] = 1;
		}
	}
}

int main() {
	int rnd = 0;
	while(scanf("%d",&N) == 1 && N) {
		memset(hav_train,0,sizeof(hav_train));
		memset(dp,0x3f3f3f3f,sizeof(dp));
		scanf("%d",&T);
		for(int i = 1; i < N; i++) {
			scanf("%d",&jian[i]);
		}
		scanf("%d",&M1);
		int timp;
		for(int i = 0; i < M1; i++) {
			scanf("%d",&timp);
			in_train(timp,0);
		}
		scanf("%d",&M2);
		for(int i = 0; i < M2; i++) {
			scanf("%d",&timp);
			in_train(timp,1);
		}
		
		dp[0][1] = 0;
		for(int i = 0; i <= T; i++) {
			for(int j = 1; j <= N; j++){
				dp[i+1][j] = min(dp[i][j]+1,dp[i+1][j]);
				if(hav_train[i][j][0]) dp[i+jian[j]][j+1] = min(dp[i+jian[j]][j+1],dp[i][j]);
				if(hav_train[i][j][1]) dp[i+jian[j-1]][j-1] = min(dp[i+jian[j-1]][j-1],dp[i][j]);
			} 
		}
		
		printf("Case Number %d: ",++rnd);
		if(dp[T][N] < 1000)	printf("%d\n",dp[T][N]);
		else printf("impossible\n");
	}

	return 0;
}


猜你喜欢

转载自blog.csdn.net/a673953508/article/details/79921501
今日推荐