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 ",p[N+1].t); } }
2月24日就整理到这里了