A Spy in the Metro UVA - 1025 (dp)

原题目不好复制,就不贴了!

题目大意:

(紫书的题意)某城市的地铁是线性的,有n(2<=n<=50)个车站,从左到右编号1-n,有M1辆车从1站开始往右开,还有M2两车从第n站开始往左开,在时刻0某人从第一站出发,目的是在时刻T,会见车站n的一个间谍。在车站等车容易被抓,所以他决定尽量在开动的火车上,让在车站等待的总时间尽量的短。列车靠站停车的时间忽略。

  输入第一行为n,

  第二行为T;

  第三行有n-1个整数t1,t2---表示从i->i+1车站的时间

  第四行为M1

  第五行为M1个数d1---dM1表示各列车的发车时间

  第六行 M2

  M2个d

 

 题解:

影响决策的只有当前时间和所处的车站,所以d(i,j)表示时刻i,你在车站j(编号1-n)最少还需要多少时间

边界:d[T,n]=0,其他为无穷

d(i,j)能发生的情况

决策一:等一分钟

决策二:搭乘往右的车(如果有)

决策三:搭乘往左的车(有)


因为时间最大为T,且小的时间是有大的时间影响的,因为边界为T,

当时刻t,在车站i的时候还要通过 t[i]和d[i]判断有没有车路过


#include <iostream>
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;

int t[55];
int has[2000][55][2];
int dp[250][150];
int main()
{
    int N,T;
    int M1,M2;
    int d;
    int k=0;
    while(scanf("%d",&N),N)
    {
        scanf("%d",&T);
        memset(has,0,sizeof(has));
        t[0]=0;
        t[N]=0;
        for(int i=1; i<N; i++)
        {
            scanf("%d",&t[i]);
        }
        scanf("%d",&M1);
        for(int i=0; i<M1; i++)
        {
            scanf("%d",&d);
            for(int j=1; j<=N; j++)
            {
                has[d+t[j-1]][j][0]=1;
                d=d+t[j-1];
            }
        }
        scanf("%d",&M2);
        for(int i=0; i<M2; i++)
        {
            scanf("%d",&d);
            for(int j=N; j>=1; j--)
            {
                has[d+t[j]][j][1]=1;
                d=d+t[j];
            }
        }
        for(int i=1; i<N; 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[i][j][0]&&i+t[j]<=T)
                {
                    dp[i][j]=min(dp[i][j],dp[i+t[j]][j+1]);
                }
                if(j>1&&has[i][j][1]&&i+t[j-1]<=T)
                {
                    dp[i][j]=min(dp[i][j],dp[i+t[j-1]][j-1]);
                }
            }
        }
        printf("Case Number %d: ",++k);
        if(dp[0][1]>=INF)printf("impossible\n");
        else printf("%d\n",dp[0][1]);
    }
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值