题目
dp[i][0] : 在第i这个木板的左端点处 跳到地面的最少时间
dp[i][1] : 在第i这个木板的右端点处 跳到地面的最少时间
#include<cstdio>
#include<cstring>
#include<algorithm>
#define m(a,b) memset(a,b,sizeof a)
using namespace std;
const int N=1e3+5,INF=0x3f3f3f3f;
struct node{int x1,x2,h;}a[N];
inline int cmp(node A,node B){return A.h<B.h;}
int dp[N][N],nex1[N],nex2[N];
int main(){
//freopen("input.txt","r",stdin);
int T;scanf("%d",&T);
while(T--){
int n,X,Y,K;scanf("%d%d%d%d",&n,&X,&Y,&K);
for(int i=1;i<=n;++i) scanf("%d%d%d",&a[i].x1,&a[i].x2,&a[i].h);
a[++n]=(node){X,X,Y};
sort(a+1,a+n+1,cmp);
m(nex1,0),m(nex2,0);
for(int i=2;i<=n;++i){
int f1=0,f2=0;
for(int j=i-1;j>=1;--j){
if(!f1&&a[j].x1<=a[i].x1&&a[i].x1<=a[j].x2&&a[i].h-a[j].h<=K) f1=1,nex1[i]=j;
if(!f2&&a[j].x1<=a[i].x2&&a[i].x2<=a[j].x2&&a[i].h-a[j].h<=K) f2=1,nex2[i]=j;
if(f1&f2) break;
}
}
m(dp,INF);
for(int i=1;i<=n;++i){
if(a[i].h<=K){
if(!nex1[i]) dp[i][0]=a[i].h;
if(!nex2[i]) dp[i][1]=a[i].h;
}
int j1=nex1[i],j2=nex2[i];
if(j1) dp[i][0]=min(a[i].x1-a[j1].x1+dp[j1][0],a[j1].x2-a[i].x1+dp[j1][1])+(a[i].h-a[j1].h);
if(j2) dp[i][1]=min(a[i].x2-a[j2].x1+dp[j2][0],a[j2].x2-a[i].x2+dp[j2][1])+(a[i].h-a[j2].h);
}
int i;
for(i=1;i<=n;++i)
if(a[i].x1==X&&a[i].x2==X&&a[i].h==Y)
{printf("%d\n",dp[i][1]);break;}
}
}