算法竞赛入门经典第九章例题9-1 uva 1025 城市里的间谍


题意:有一个间谍,在1号车站,T时间后,要在n车站会见另一个间谍。在车站容易被人发现,所以他想通过来回做列车来尽可能减少在车站等待的时间(换成和上下站不消耗时间)。求在车站等待的最少时间。

思路:在某个车站上时一共有三种选择1、等1分钟;2、搭向右 的列车;3、搭向左的火车。(其中2,3不一定满足)。那么依照书上想法很容易想到dp[i][j]分别表示在第i个时间时在车站j的策略下等待的最小时间。


#include 
#include 
#include 
#include 
#define INF 0x3fffffff
using namespace std;


int ti[22];
int to_right[55];
int to_left[55];
bool has_train[220][55][2];
int dp[220][55];

int main()
{
    int n,T,M1,M2,cas = 1;
    while(~scanf("%d",&n) && n){
        memset(has_train,false,sizeof has_train);
        scanf("%d",&T);
        for(int i = 1;i<=n-1;i++)
            scanf("%d",&ti[i]);

        scanf("%d",&M1);
        for(int i =1;i<=M1;i++)
            scanf("%d",&to_right[i]);

        scanf("%d",&M2);
        for(int i =1;i<=M2;i++)
            scanf("%d",&to_left[i]);

        for(int i = 1;i<=M1;i++){
            int t = to_right[i],cnt = 1;
            while(t <= T && cnt <= n){
                has_train[t][cnt][0] = true;
                t+=ti[cnt++];
            }
        }

        for(int i =1;i<=M2;i++){
            int t = to_left[i],cnt = n;
            while(t<=T && cnt >=1){
                has_train[t][cnt][1] = true;
                t+=ti[--cnt];
            }
        }
        
        //书上的代码
        for(int i =1;i<=n-1;i++) dp[T][i] = INF;
        dp[T][n] = 0;
        for(int i = T-1;i>=0;i--){
            for(int j = 1;j<=n;j++){
                dp[i][j] = dp[i+1][j] + 1;
                if(j < n && has_train[i][j][0] && i+ti[j] <= T){
                    dp[i][j] = min(dp[i][j],dp[i+ti[j]][j+1]);
                }
                if(j > 1 && has_train[i][j][1] && i+ti[j-1] <= T){
                    dp[i][j] = min(dp[i][j],dp[i+ti[j-1]][j-1]);
                }
            }
        }
        printf("Case Number %d: ",cas++);
        if(dp[0][1] >= INF) puts("impossible");
        else printf("%d\n",dp[0][1]);

    }
    return 0;
}


你可能感兴趣的:(Acm)