题目链接:http://poj.org/problem?id=1661
下图是左边的,右边的同理:
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<algorithm> using namespace std; #define N 1100 #define INF 0xffffff struct node { int L, R, H; } a[N]; int cmp(node p, node q) { return p.H > q.H; } int main() { int T, n, x, y, m,dp[N][2]; scanf("%d", &T); while(T--) { scanf("%d %d %d %d", &n, &x, &y, &m); for(int i=1; i<=n; i++) { scanf("%d %d %d", &a[i].L, &a[i].R, &a[i].H); dp[i][0] = dp[i][1] = INF; } int ans=INF; a[0].L = x; a[0].R = x; a[0].H = y; sort(a, a+n+1, cmp);///按高度排序; a[n+1].L = -22222; a[n+1].R = 22222; a[n+1].H = 0;///地面; dp[0][0] = dp[0][1] = 0; for(int i=0; i<=n; i++) { int LL=1, RR=1;///LL和RR用于标记从第i块木板左右两端下落是否找到了下一个落脚点 for(int j=i+1; j<=n+1; j++) { if( (!LL&&!RR) || (a[i].H-a[j].H>m) )///当不满足高度或者已经有下一落点时就可以跳出来了; break; if(a[i].L>=a[j].L && a[i].L<=a[j].R && a[i].H!=a[j].H && LL)///当i从左边下落到下一平台j时; { LL=0;///已经在左边找到落点; if(j==n+1)///如果落点为地面就可以取最小值了; ans=min(ans, dp[i][0]); else///否侧就。。。画个图,一眼就看明白了; { dp[j][0]=min(dp[j][0], dp[i][0]+(a[i].L-a[j].L)); dp[j][1]=min(dp[j][1], dp[i][0]+(a[j].R-a[i].L)); } } if(a[i].R>=a[j].L && a[j].R>=a[i].R && a[i].H!=a[j].H && RR)///和上面同理; { RR=0; if(j==n+1) ans=min(ans, dp[i][1]); else { dp[j][0]=min(dp[j][0], dp[i][1]+(a[i].R-a[j].L)); dp[j][1]=min(dp[j][1], dp[i][1]+(a[j].R-a[i].R)); } } } } printf("%d ", ans+y); } return 0; }