Help Jimmy POJ - 1661

原题链接

考察:线性dp

错误思路:

        f[x][y]代表坐标(x,y)的最少时间,状态转移方程推不出来,而且完全没有用到木板

正确思路:

        上面的状态表示其实比较接近.dp问题要将大问题分解为若干个小问题.将起始点看作一块木板,f[i][0]表示从左边跳下去的最短时间,f[i][1]表示从右边跳下去的最短时间.,每一个新的状态都由右边或者左边转移而来,两者求min.

要注意的是:当从某端点已经确定会掉在某块木板上时,就不可能掉在其他木板上

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <algorithm>
 5 using namespace std;
 6 const int N = 1010,INF = 0x3f3f3f3f;
 7 struct FLoor{
 8     int l,r,h;
 9     bool operator<(FLoor x)
10     {
11         if(this->h==x.h) return this->l<x.l;
12         return this->h<x.h;
13     }
14 }floors[N];
15 int f[N][2];
16 void get(int i,int j,bool dir)
17 {
18     int l = floors[i].l,r = floors[i].r;
19     int a = floors[j].l,b = floors[j].r;
20     int h = floors[i].h-floors[j].h;
21     if(!dir)//从第i块的左边跳到第j的木块的左,右 
22     {
23         int x = abs(l-a),y = abs(l-b);
24         f[i][dir] = min(x+f[j][0],y+f[j][1])+h;
25     }else{
26         int x = abs(r-a),y = abs(r-b);
27         f[i][dir] = min(x+f[j][0],y+f[j][1])+h;
28     }
29 }
30 int main()
31 {
32     int T;
33     scanf("%d",&T);
34     while(T--)
35     {
36         int n,x,y,maxn;
37         scanf("%d%d%d%d",&n,&x,&y,&maxn);
38         for(int i=1;i<=n;i++) 
39           scanf("%d%d%d",&floors[i].l,&floors[i].r,&floors[i].h);
40         sort(floors+1,floors+n+1);
41         floors[0].h = 0,floors[0].l = -INF,floors[0].r = INF;
42         floors[n+1].l = x,floors[n+1].r =x,floors[n+1].h = y;
43         for(int i=1;i<=n+1;i++)
44         {
45             f[i][1] = INF,f[i][0] = INF;
46             bool okl = 1,okr = 1;
47             for(int k=i-1;k>=1;k--)
48             {
49                 int h = floors[i].h-floors[k].h;
50                 if(h>maxn) break;
51                 int l = floors[i].l,r= floors[i].r;
52                 if(okl&&l>=floors[k].l&&l<=floors[k].r)
53                     get(i,k,0),okl = 0;
54                 if(okr&&r>=floors[k].l&&r<=floors[k].r)
55                     get(i,k,1),okr = 0;
56             }
57             if(floors[i].h<=maxn)
58             {
59                 if(okl) f[i][0] = min(f[i][0],floors[i].h);
60                 if(okr) f[i][1] = min(f[i][1],floors[i].h);
61             }
62         }
63         printf("%d\n",f[n+1][0]);
64     }
65     return 0;
66 }

 

posted @ 2021-03-15 07:33  acmloser  阅读(41)  评论(0编辑  收藏  举报