POJ-1661 Help Jimmy

题意:老鼠从某点开始下落,1m/s,它跑动的速度也是1米/秒,其中有很多平台,当Jimmy跑到平台的边缘时,开始继续下落。Jimmy每次下落的高度不能超过MAX米,不然就会摔死,游戏也会结束。

思路:DP,开个二维数组dp[1010][2]保存走左右边缘的最小值~

题目连接:http://poj.org/problem?id=1661

 

View Code
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <string>
 6 #include <algorithm>
 7 #include <iostream>
 8 using namespace std;
 9 const int N=1010;
10 const int inf=1<<30;
11 
12 typedef struct In{
13     int l,r,h;
14 }In;
15 In a[N];
16 int dp[N][2];
17 
18 int cmp(In a,In b){
19     return a.h>b.h;
20 }
21 
22 int main(){
23     
24 //    freopen("data.in","r",stdin);
25 //    freopen("data.out","w",stdout);
26     
27     int t,N,Y,X,MAX;
28     scanf("%d",&t);
29     while(t--){
30         scanf("%d%d%d%d",&N,&X,&Y,&MAX);
31         a[0].l=a[0].r=X;
32         a[0].h=Y;
33         for(int i=1;i<=N;i++)
34             scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].h);
35         sort(a+1,a+N+1,cmp);
36         memset(dp,0x0f0f0f0f,sizeof(dp));
37         dp[0][0]=dp[0][1]=0;
38         for(int i=0;i<=N;i++){
39             for(int j=i+1;j<=N;j++){
40                 if(a[i].h-a[j].h<=MAX){
41                     if(a[j].l<=a[i].l&&a[j].r>=a[i].l){
42                         dp[j][0]=min(dp[j][0],dp[i][0]+a[i].l-a[j].l+a[i].h-a[j].h);
43                         dp[j][1]=min(dp[j][1],dp[i][0]+a[j].r-a[i].l+a[i].h-a[j].h);
44                         break;
45                     }
46                 }
47             }
48             for(int j=i+1;j<=N;j++){
49                 if(a[i].h-a[j].h<=MAX){
50                     if(a[j].l<=a[i].r&&a[j].r>=a[i].r){
51                         dp[j][0]=min(dp[j][0],dp[i][1]+a[i].r-a[j].l+a[i].h-a[j].h);
52                         dp[j][1]=min(dp[j][1],dp[i][1]+a[j].r-a[i].r+a[i].h-a[j].h);
53                         break;
54                     }
55                 }
56             }
57         }
58         int MIN=inf;
59         for(int i=N;i>=0;i--){
60             if(a[i].h>MAX) break;
61             bool flag=false;
62             for(int j=i+1;j<=N;j++){
63                 if(a[j].l<=a[i].l&&a[j].r>=a[i].l){
64                     flag=true;
65                     break;
66                 }
67             } 
68             if(!flag) MIN=min(MIN,dp[i][0]+a[i].h);
69             flag=false;
70             for(int j=i+1;j<=N;j++){
71                 if(a[j].l<=a[i].r&&a[j].r>=a[i].r){
72                     flag=true;
73                     break;
74                 }
75             } 
76             if(!flag) MIN=min(MIN,dp[i][1]+a[i].h);
77         }
78         printf("%d\n",MIN);
79     }
80     return 0;
81 }

转载于:https://www.cnblogs.com/Hug-Sea/articles/2526949.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值