POJ 1661 Help Jimmy DP

思路:Jimmy 跳到一块板上后,可以有两种选择,向左走或向右走。走到左端和走到右端所需的时间,容易算出。

n如果我们能知道,以左端为起点到达地面的最短时间,和以右端为起点到达地面的最短时间,那么向左走还是向右走,就很容选择了。

n因此,整个问题就被分解成两个子问题,即Jimmy 所在位置下方第一块板左端为起点到地面的最短时间,和右端为起点到地面的最短时间。这两个子问题在形式上和原问题是完全一致的。
详见代码
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<iostream>
 5 #define clc(a,b) memset(a,b,sizeof(a))
 6 #define LL long long
 7 #include<cmath>
 8 const int inf=0x3f3f3f3f;
 9 using namespace std;
10 int n,X,Y,maxx;
11 int dp[1010][2];//0表示左边,1表示右边
12 struct node {
13     int x,y,h;
14 } plat[1010];
15 
16 int cmp(node p,node q) {
17     return p.h<q.h;
18 }
19 
20 void left_solve(int i) {
21     int k=i-1;
22     while(k>0&&plat[i].h-plat[k].h<=maxx) {
23         if(plat[i].x>=plat[k].x&&plat[i].x<=plat[k].y) {
24             dp[i][0]=plat[i].h-plat[k].h+min(plat[i].x-plat[k].x+dp[k][0],plat[k].y-plat[i].x+dp[k][1]);//转移方程
25             return ;
26         } else
27             k--;
28     }
29     if(plat[i].h-plat[k].h>maxx)
30         dp[i][0]=inf;
31     else
32         dp[i][0]=plat[i].h;
33 }
34 
35 void right_solve(int i) {
36     int k=i-1;
37     while(k>0&&plat[i].h-plat[k].h<=maxx) {
38         if(plat[i].y>=plat[k].x&&plat[i].y<=plat[k].y) {
39             dp[i][1]=plat[i].h-plat[k].h+min(plat[i].y-plat[k].x+dp[k][0],plat[k].y-plat[i].y+dp[k][1]);
40             return;
41         } else
42             k--;
43     }
44     if(plat[i].h-plat[k].h>maxx)
45         dp[i][1]=inf;
46     else
47         dp[i][1]=plat[i].h;
48 
49 }
50 int solve() {
51     for(int i=1; i<=n+1; i++) {
52         left_solve(i);
53         right_solve(i);
54     }
55     return min(dp[n+1][0],dp[n+1][1]);
56 }
57 
58 int main() {
59 //    freopen("in.txt","r",stdin);
60     int t;
61     while(~scanf("%d",&t)) {
62         while(t--) {
63             scanf("%d%d%d%d",&n,&X,&Y,&maxx);
64             for(int i=1; i<=n; i++) {
65                 scanf("%d%d%d",&plat[i].x,&plat[i].y,&plat[i].h);
66             }
67             plat[0].x=-20000;//加入地面和起始点
68             plat[0].y=20000;
69             plat[0].h=0;
70             plat[n+1].x=X;
71             plat[n+1].y=X;
72             plat[n+1].h=Y;
73             sort(plat,plat+n+2,cmp);//从低到高排序
74 //            for(int i=0;i<=n+1;i++){
75 //            printf("%d
",plat[i].h);
76 //            }
77             clc(dp,0);
78             printf("%d
",solve());
79         }
80     }
81     return 0;
82 }
View Code
原文地址:https://www.cnblogs.com/ITUPC/p/5288504.html