Simple DP, each line segment records two values, to the left endpoint minimum time and to the end of the minimum time. Follow this backwards derivation.
#include <cstdio>#include<cstring>#include<cmath>#include<stack>#include<vector>#include<string>#include<iostream>#include<algorithm>using namespacestd;Const intmaxn= ++Ten;intT;intN,x,y,max;structw{intX1,x2,h;} S[MAXN];intDPLEFT[MAXN],DPRIGHT[MAXN];BOOLcmpConstW&a,Constw&b) { returnA.h>b.h;}intMain () {scanf ("%d",&T); while(t--) {scanf ("%d%d%d%d",&n,&x,&y,&MAX); s[0].x1=x,s[0].x2=x,s[0].h=x; for(intI=1; i<=n; i++) scanf ("%d%d%d",&s[i].x1,&s[i].x2,&s[i].h); S[n+1].x1=-0x7fffffff, s[n+1].x2=0x7FFFFFFF, s[n+1].h=0; for(intI=0; i<=n+1; i++) dpright[i]=dpleft[i]=0x7fffffff; Sort (S+1, s+n+1, CMP); dpleft[0]=0, dpright[0]=0; intans=0x7FFFFFFF; for(intI=0; i<=n; i++) { //falling from the left if(dpleft[i]!=0x7fffffff) { for(intj=i+1; j<=n+1; J + +) { if(s[j].x1<=s[i].x1&&s[i].x1<=s[j].x2) { if(s[i].h-s[j].h<=MAX) { if(j==n+1) { intcost=dpleft[i]+s[i].h-s[j].h; Ans=min (ans,cost); } Else { intCost ; //the time required to the left sideCost=dpleft[i]+s[i].h-s[j].h+s[i].x1-s[j].x1; DPLEFT[J]=min (cost,dpleft[j]); //time required to the right endcost=dpleft[i]+s[i].h-s[j].h+s[j].x2-s[i].x1; DPRIGHT[J]=min (cost,dpright[j]); } } Break; } } } //Go right . if(dpright[i]!=0x7fffffff) { for(intj=i+1; j<=n+1; J + +) { if(s[j].x1<=s[i].x2&&s[i].x2<=s[j].x2) { if(s[i].h-s[j].h<=MAX) { if(j==n+1) { intcost=dpright[i]+s[i].h-s[j].h; Ans=min (ans,cost); } Else { intCost ; //the time required to the left sidecost=dpright[i]+s[i].h-s[j].h+s[i].x2-s[j].x1; DPLEFT[J]=min (cost,dpleft[j]); //time required to the right endcost=dpright[i]+s[i].h-s[j].h+s[j].x2-s[i].x2; DPRIGHT[J]=min (cost,dpright[j]); } } Break; } }}} printf ("%d\n", ans); } return 0;}
POJ 1661 Help Jimmy