zoukankan      html  css  js  c++  java
  • POJ 1661-Help Jimmy-dp

    一道dp模拟题。

    给n个板子和一个初始坐标xy,从x,y开始向下跳,有一个最高的下跳距离。

    在板子上走和下跳都消耗时间。计算到达地面的最短时间。

    把板子按高度排序

    dp[i][0]表示到达第i块板子左边沿的时间,dp[i][1]表示到达右边沿的时间。

    则 dp[i][0] = min(dp[k][0]+f(),dp[k][1]+f() ) k为小于i的可以跳到i上的板子。f()表示从k的左/右边沿到i的左边沿需要的时间。

       dp[i][1] = min(dp[k][0]+f(),dp[k][1]+f())

    注意判断k是否能跳到i上比较麻烦,k这一端的坐标在i内,且k还没有往下跳的板子,因为一块板子的一端只可能跳到唯一的一块板子,或者地面。

    最后维护可以直接跳到地面的板子一端的dp值的最小值。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 
      5 using namespace std;
      6 
      7 const int maxn = 1000+10;
      8 const int INF = 0x3f3f3f3f;
      9 
     10 struct Table{
     11     int l,r;
     12     int height;
     13     bool operator < (const Table &rhs) const
     14     {
     15         return height > rhs.height;
     16     }
     17 }table[maxn];
     18 
     19 int N,X0,Y0,Max;
     20 int T;
     21 int dp[maxn][2];
     22 int vis[maxn],next[maxn][2];
     23 
     24 bool check(int i,int j)
     25 {
     26     if(table[j].height - table[i].height <= Max && table[j].height != table[i].height)
     27         return true;
     28     else
     29         return false;
     30 }
     31 
     32 int main()
     33 {
     34     scanf("%d",&T);
     35     while(T--)
     36     {
     37         scanf("%d%d%d%d",&N,&X0,&Y0,&Max);
     38         for(int i=1;i<=N;i++)
     39         {
     40             scanf("%d%d%d",&table[i].l,&table[i].r,&table[i].height);
     41             if(table[i].l > table[i].r)
     42                 swap(table[i].l,table[i].r);
     43         }
     44 
     45         sort(table+1,table+1+N);
     46         memset(vis,0,sizeof vis);
     47         memset(next,0,sizeof next);
     48 
     49         for(int i=0;i<=N;i++)
     50             dp[i][0] = dp[i][1] = INF;
     51         int ans = INF;
     52         int flag = 0;
     53 
     54         for(int i=1;i<=N;i++)
     55         {
     56             if(Y0 - table[i].height > Max) break;
     57             if(X0 >= table[i].l && X0 <= table[i].r)
     58             {
     59                 dp[i][0] = Y0 - table[i].height + X0 - table[i].l;
     60                 dp[i][1] = Y0 - table[i].height + table[i].r - X0;
     61                 vis[i] = true;
     62                 flag = 1;
     63                 break;
     64             }
     65         }
     66 
     67         if(!flag)
     68         {
     69             printf("%d
    ",Y0);
     70             continue;
     71         }
     72 
     73         for(int i=1;i<=N;i++)
     74         {
     75             for(int j=i-1;j>=1;j--) if(check(i,j) && vis[j])
     76             {
     77                 if(!next[j][0] && table[j].l <= table[i].r && table[j].l >= table[i].l)
     78                 {
     79                     next[j][0] = true;
     80                     vis[i] = true;
     81                     dp[i][0] = min(dp[j][0]+table[j].height-table[i].height+table[j].l-table[i].l,dp[i][0]);
     82                     dp[i][1] = min(dp[j][0]+table[j].height-table[i].height+table[i].r-table[j].l,dp[i][1]);
     83                 }
     84                 if(!next[j][1] && table[j].r >= table[i].l && table[j].r <= table[i].r )
     85                 {
     86                     next[j][1] = true;
     87                     vis[i] = true;
     88                     dp[i][0] = min(dp[j][1]+table[j].height-table[i].height+table[j].r-table[i].l,dp[i][0]);
     89                     dp[i][1] = min(dp[j][1]+table[j].height-table[i].height+table[i].r-table[j].r,dp[i][1]);
     90                 }
     91             }
     92             //printf("l:%d r:%d 
    ",dp[i][0],dp[i][1]);
     93         }
     94 
     95         for(int i=N;i>=1;i--) if(vis[i] && table[i].height <= Max)
     96         {
     97             if(!next[i][0]) ans = min(ans,dp[i][0]+table[i].height);
     98             if(!next[i][1]) ans = min(ans,dp[i][1]+table[i].height);
     99 
    100             //printf("h:%d l:%d r:%d [%d,%d] 
    ",table[i].height,dp[i][0],dp[i][1],next[i][0],next[i][1]);
    101         }
    102         printf("%d
    ",ans);
    103     }
    104 }

    最近做了好多dp水题,然而不想上传,太水了。

  • 相关阅读:
    【Linux常用命令】 cat
    【Linux常用命令】 chmod
    【2012.4.22】北京植物园&卧佛寺
    【Linux常用命令】 重定向输出 > 和 >>
    一些话
    linux下查看用户个数和具体名字
    【Linux常用命令】 ls
    Ethernet frame
    防止修改类和方法
    redis数据批量导入导出
  • 原文地址:https://www.cnblogs.com/helica/p/5528150.html
Copyright © 2011-2022 走看看