POJ 1661 Help Jimmy

简单的DP,利用重叠子问题,详见代码


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map> 
using namespace std;
#define N 1010
int d[N][2];

struct stage{
       int l, r, h;
       int lnext, rnext; 
       stage(int x = 0, int y = 0, int z = 0):l(x), r(y), h(z){} 
        
}a[N];

int n, mx;
const int inf = 1000000000;
 



     
int doit(int cur, int flag){
     if (d[cur][flag] != -1)return d[cur][flag];
     d[cur][flag] = inf;
     int pos = flag?a[cur].r:a[cur].l;  
     int des = flag?a[cur].rnext:a[cur].lnext; 
     int dif =a[cur].h - a[des].h;  
     if (dif > mx)return d[cur][flag];
     else  if (des == n - 1){
           return d[cur][flag] =  (dif);
     }
     else {
           int num = dif + min(pos - a[des].l + doit(des, 0), a[des].r - pos + doit(des, 1)); 
           d[cur][flag] = min(num, d[cur][flag]); 
           return d[cur][flag];
     } 
} 
      
      


bool cmpp(stage a, stage b){
     return a.h > b.h;
} 
 
int main(){
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout); 
    int t;
    scanf("%d", &t);
    while (t--){
          int x, y, l, r;
          scanf("%d %d %d %d", &n, &x, &y, &mx);
          a[0] = stage(x, x, y);
          for (int i = 1; i <= n; i++){
              scanf("%d %d %d" , &l, &r, &y);
              a[i] = stage(l, r, y);
          }
          a[n + 1] = stage(-20000, 20000, 0);
          n += 2; 
          sort(a, a + n, cmpp);
          for (int i = 0; i < n - 1; i++){
              for (int j = i + 1; j < n; j++){
                  if (a[j].h < a[i].h){
                             if (a[j].l <= a[i].l && a[j].r >= a[i].l){
                                        a[i].lnext = j;
                                        break;
                             }
                  }
              }
              for (int j = i + 1; j < n; j++){
                  if (a[j].h < a[i].h){
                             if (a[j].l <= a[i].r && a[j].r >= a[i].r){
                                        a[i].rnext = j;
                                        break;
                             }
                  }
              }
          } 
          for (int i = 0; i < n; i++)d[i][0] = d[i][1] = -1; 
          doit(0, 0);
          printf("%d\n", d[0][0]); 
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值