zoukankan      html  css  js  c++  java
  • 9-1 A Spy in the Metro uva1025 城市里的间谍 (DP)

      非常有价值的dp题目  也是我做的第一题dp    真的效率好高

    题意:某城市的地铁是线性的 有n个车站 从左到右编号为1-n  有m1辆列车从第一站开始往右开 还有m2辆列车从第n站开始往左开  在时刻0  小明从第1站出发  目的是在时刻T 正好会见在第n站的间谍  为了不被抓   小明在车站等待的时间要尽量少   求出最短时间  如果到不了  输出impossible 

    输入第一行为n  第二行为T  第三行有n-1个数字  表示 从左到右两个车站之间列车行驶的时间   接下来为m1    然后跟着m1个数字 表示车站1发车时刻   然后m2 同理   

    一开始根本想不到用dp   这题的元素好多 !!   

    每次有三种决策   

    1 原地等待1s

    2 搭乘往右的车  (当然 前提是有)

    3 搭乘往左的车

    当面临多决策问题时  且所处环境(时间 地点)多样时   用dp做!!!

    影响决策的元素只有两个  1 时间  2 所处车站

    所以 dp i j     i表示当前时刻   j 表示所处车站

    从结束点  也就是 时刻为T时开始进行dp  

    注意对dp数组的初始化   都在i=T的情况下   当i==n时   达成目标   dp为0     当i为其他值时  全部为inf(显然已经没机会了)

    非常好的dp  !!

    #include<bits/stdc++.h>
    using namespace std;
    #define N 200+5
    #define inf 0x3f3f3f3f
    int n,t[N],car[N][N][2];
    int dp[N][N];
    int main()
    {
       int cas=0;
       int T;
       int q;
        int x;
       while(scanf("%d",&n)==1,n)
       {
    
           memset(car,0,sizeof car);
           scanf("%d",&T);
           for(int i=0;i<n-1;i++)scanf("%d",&t[i]);
           
           scanf("%d",&q);
           while(q--)
           {
           scanf("%d",&x);
           car[0][x][0]=1;
           for(int i=1;i<n;i++)
            {
               x+=t[i-1];
               car[i][ x ][0]=1;
            }
           }
           scanf("%d",&q);
           while(q--)
           {
               scanf("%d",&x);
               car[n-1][x][1]=1;
               for(int i=n-2;i>=0;i--)
               {
                   x+=t[i];
                   car[i][x][1]=1;
               }
           }
    
        for(int i=0;i<n-1;i++)dp[T][i]=inf;//其他的完全不用初始化   填表会全部覆盖掉
         dp[T][n-1]=0;
         for(int i=T-1;i>=0;i--)//顺序必须是固定的
            for(int j=0;j<n;j++)
         {
             dp[i][j]=dp[i+1][j]+1;//原地等待一秒钟
             
             if( car[j][i][0] && i+t[j]<=T && j<n-1 )
                dp[i][j]=min(dp[i][j],dp[ i+t[j] ][j+1]  );
    
             if( car[j][i][1] && j!=0 && i+t[j-1]<=T )
                dp[i][j]=min(dp[i][j],dp[ i+t[j-1] ][j-1]);
         }
    
         printf("Case Number %d: ",++cas);
         if(dp[0][0]>=inf)
            printf("impossible
    ");
         else
            printf("%d
    ",dp[0][0]);
       }
        return 0;
    }
  • 相关阅读:
    高数基础知识整理12.微分方程
    x(1-x)及其更高次在区间[0,1]上的积分值
    PHP中的http协议
    php简单实现MVC
    如何用jQuery获得select的值
    面向对象思想介绍
    MySQL 日期和时间戳的转换 | 以及DATE_FORMAT()用法
    js将时间转换为时间戳
    PHP中sql语句如何使用变量
    四种简单的sql语句(增删改查语句)
  • 原文地址:https://www.cnblogs.com/bxd123/p/10449831.html
Copyright © 2011-2022 走看看