1. 程式人生 > >動態規劃——A Spy in the Metro UVA - 1025

動態規劃——A Spy in the Metro UVA - 1025

題解:

這道題目基本上是線性dp,,只需要在記率每個時刻,每個車站左邊或者右邊有木有車駛來,

一共有三種狀態(等待,上左車,上右車),就可以判斷下一狀態需要等待的時間了,具體解法紫書上有說明

注意點:需要注意你儲存每一站的時間的下標是怎樣的,然後根據你的下標在你記錄車輛的時候注意下標,dp的時候也要注意下標

 

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

typedef long long ll;
const int inf = 0x3f3f3f3f;

int n,t;        //車站數和約定的時間
int tim[55];    //每個車站的行走時間
int m1,m2;
int hav_train[300][55][2];  //某個時間點某個車站某個方向有木有車
int dp[255][55];    //某個時間某個車站的已經等待時間

void add_train(int tt, int f) { //某個時間某個方向發車
    if(!f) {
        hav_train[tt][1][0] = 1; //f為0車站從右邊出發
        for(int i = 1; i < n-1; i++) {
            tt = tt+tim[i];
            if(tt > 200) break;   //已經超過約定的最大時間
            hav_train[tt][i+1][0] = 1; //f為0車站從右邊出發
        }
    }
    else {
        hav_train[tt][n][1] = 1;
        for(int i = n-1; i > 1; i--) {
            tt = tt+tim[i];
            if(tt > 200) break;   //已經超過約定的最大時間
            hav_train[tt][i][1] = 1; //f為0車站從右邊出發
        }
    }
}

int main()
{
    //freopen("in.txt","r",stdin);

    int rnd = 0;
    while(scanf("%d",&n) == 1 && n) {
        memset(hav_train,0,sizeof(hav_train));

        scanf("%d",&t);
        for(int i = 1; i <= n-1; i++)   //只有n-1個間隔
            scanf("%d",&tim[i]);    //1代表1-2的時間

        int tmp;
        scanf("%d",&m1);
        for(int i = 0; i < m1; i++) {
            scanf("%d",&tmp);
            add_train(tmp,0);
        }
        scanf("%d",&m2);
        for(int i = 0; i < m2; i++) {
            scanf("%d",&tmp);
            add_train(tmp,1);
        }

        memset(dp,inf,sizeof(dp));
        dp[0][1] = 0;   //0時刻第一個車站等待時間為0
        for(int i = 0; i <= t; i++) {   //遍歷每個時間和車站
            for(int j = 1; j <= n; j++) {
                dp[i+1][j] = min(dp[i+1][j],dp[i][j]+1);
                if(hav_train[i][j][0]) dp[i+tim[j]][j+1] = min(dp[i+tim[j]][j+1],dp[i][j]);
                if(hav_train[i][j][1]) dp[i+tim[j-1]][j-1] = min(dp[i+tim[j-1]][j-1],dp[i][j]);
            }
        }

        if(dp[t][n] < inf) printf("Case Number %d: %d\n",++rnd,dp[t][n]);
        else printf("Case Number %d: impossible\n",++rnd);
    }

    return 0;
}