A Spy in the Metro


看了两天终于看懂了,但是思路还是不太好想

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int n,m;
int dp[255][255],dpp[255][255][3],mk[255];//  dp是动态规划数组  dpp[i][j][0]的意思就是在时间i上j站点有没有向左去的列车
int inf=0x3f3f3f3f;                       //    dpp[i][j][1]的意思就是在时间i上j站点有没有向右去的列车  mk存储到下一个站点所要的时间
int casee=0;
int main()
{
    while(~scanf("%d",&n)&&n)
    {
        scanf("%d",&m);
        for(int i=1; i<n; i++)
            scanf("%d",&mk[i]);
        memset(dpp,0,sizeof(dpp));          //因为dpp数组是找出在某个时间上的某个站点有没有火车,所以初始化
        int ta,ca,tb;
        scanf("%d",&ta);
        while(ta--)
        {
            scanf("%d",&ca);  //在站点起始处,在ca时间发一趟列车
            for(int i=1; i<n; i++)
            {
                if(ca<=m)
                    dpp[ca][i][0]=1;  //标记有列车
                ca+=mk[i];   //计算出到下一个站点什么时候有车,最后一个站点不用计算
            }                //是因为dpp数组存的是这个站点什么时候有向右的的车,最后一个站点没有向右的车,所以不用计算
        }
        scanf("%d",&tb);
        while(tb--)
        {
            scanf("%d",&ca);
            for(int i=n-1; i>=1; i--)
            {
                if(ca<=m)
                    dpp[ca][i+1][1]=1;//同理上面的计算过程,至于i+1是因为在上面
                ca+=mk[i];     //存储到下一站的时间的时候的问题,现在计算的是向左
            }                   //的,所以在计算这个站点是否有车的时候,计算时的i与存储
        }                        //时的i有差值,所以要+1;
        for(int i=1;i<n;i++)
            dp[m][i]=inf;
        dp[m][n]=0;          //
        for(int i=m-1;i>=0;i--)// m代表时间
        {
            for(int j=1;j<=n;j++)  // n代表车站数
            {
                dp[i][j]=dp[i+1][j]+1;   //因为间谍只能通过火车移动,所以假如没有列车的话只能在原地等候
                if(j<n&&dpp[i][j][0]&&i+mk[j]<=m)   //判断还需不需要往右走
                    dp[i][j]=min(dp[i][j],dp[i+mk[j]][j+1]);  //因为时间是在不断减小的,所以为了让等待的时间尽可能的小现在就是有列车就是上,上了列车就代表多加一站
                if(j>1&&dpp[i][j][1]&&i+mk[j-1]<=m)   //判断向左走
                    dp[i][j]=min(dp[i][j],dp[i+mk[j-1]][j-1]);
            }
        }
        printf("Case Number %d: ",++casee);
        if(dp[0][1]>=inf)
            printf("impossible\n");
        else
            printf("%d\n",dp[0][1]);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值