POJ - 1661 - Help Jimmy - 简单dp

http://poj.org/problem?id=1661

一般化处理,把一开始的落地和大地都视作平台,设计平台类的属性。dp的时候显然是从上往下dp的,而且要小心Jimmy不能够穿过平台,也就是从平台左侧掉下或者从右侧掉下都只能有一次。

#include<cmath>
#include<algorithm>
#include<iostream>
#include<cstdio>
using namespace std;
#define ll long long

int N,X,Y,MAX;

struct P{
    int lx,rx,y;
    int lt,rt;
    int t;
    bool operator<(P that){
        return y>that.y;
    }
}p[1005];

void update(int id){
    int leftblock=0;
    int rightblock=0;
    for(int i=id+1;i<N+2;i++){
        int dh=p[id].y-p[i].y;
        if(dh>MAX)
            return;
        if(leftblock==0&&p[i].lx<=p[id].lx&&p[i].rx>=p[id].lx){
            p[i].lt=min(p[i].lt,p[id].lt+dh+abs(p[id].lx-p[i].lx));
            p[i].rt=min(p[i].rt,p[id].lt+dh+abs(p[id].lx-p[i].rx));
            p[i].t=min(p[i].t,p[id].lt+dh);
            leftblock=1;
        }

        if(rightblock==0&&p[i].lx<=p[id].rx&&p[i].rx>=p[id].rx){
            p[i].lt=min(p[i].lt,p[id].rt+dh+abs(p[id].rx-p[i].lx));
            p[i].rt=min(p[i].rt,p[id].rt+dh+abs(p[id].rx-p[i].rx));
            p[i].t=min(p[i].t,p[id].rt+dh);
            rightblock=1;
        }
        //cout<<"i="<<i<<" "<<p[i].lt<<" "<<p[i].rt<<" "<<p[i].t<<endl;

    }
}

int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d%d%d",&N,&X,&Y,&MAX);
        p[0].lx=p[0].rx=X;
        p[0].y=Y;
        p[0].lt=p[0].rt=p[0].t=0;
        for(int i=1;i<N+1;i++){
            scanf("%d%d%d",&p[i].lx,&p[i].rx,&p[i].y);
            p[i].lt=p[i].rt=p[i].t=0x3f3f3f3f;
        }
        p[N+1].lx=-30000;
        p[N+1].rx=30000;
        p[N+1].y=0;
        p[N+1].lt=p[N+1].rt=p[N+1].t=0x3f3f3f3f;
        sort(p,p+N+2);
        for(int i=0;i<N+2;i++){
            update(i);
            //cout<<p[i].lt<<" "<<p[i].rt<<" "<<p[i].t<<endl;
        }

        printf("%d\n",p[N+1].t);
    }
}

 2月24日就整理到这里了

posted @ 2019-01-22 14:57  韵意  阅读(143)  评论(0编辑  收藏  举报