题目链接: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;
}