把平台按高度排序,从前面的平台开始往下找,找到最近的一个平台,记录下来的点,以后不再能从该点下来了,因为小人不能穿过平台直接下落,最后到达地面的时候特殊处理一下
dp[i].x1:到达第i个平台左端点的最短时间
dp[i].x2:到达第i个平台右端点的最短时间
递推式:dp[j].x1=min(dp[i].x2+a[i].h-a[j].h+a[i].x2-a[j].x1,dp[j].x1);
dp[j].x2=min(dp[i].x2+a[i].h-a[j].h+a[j].x2-a[i].x2,dp[j].x2);
再总结一下,当出现WA的时候不要急着去找数据,改代码,先静下心来想一想自己思路有没有不对的地方,初始化的时候有没有做好
刚开始wa了一次,就是因为初始化的时候一点点写错了,还好检查初始化的时候马上就发现问题了
#include<stdio.h>
#include<algorithm>
using namespace std;
const int inf=99999999;
int n,x,y,ma;
struct Node{
int x1,x2,h;
}a[1005];
Node dp[1005],vis[1005];
int cmp(Node a,Node b){
return a.h>b.h;
}
void init(){
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++){
dp[i].x1=inf;
dp[i].x2=inf;
vis[i].x1=0;
vis[i].x2=0;
}
vis[0].x1=0;vis[0].x1=0;
a[0].x1=x;a[0].x2=x;a[0].h=y;
dp[0].x1=0;dp[0].x2=0;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d%d%d",&n,&x,&y,&ma);
for(int i=1;i<=n;i++) {
int x1,x2,h;
scanf("%d%d%d",&x1,&x2,&h);
if(h<y){
a[i].x1=x1; a[i].x2=x2; a[i].h=h;
}
else{
i--;
n--;
}
}
n++;
a[n].x1=-inf;a[n].x2=inf;a[n].h=0;
init();
int ans=inf;
for(int i=0;i<=n;i++){
for(int j=i+1;j<=n&&a[i].h-a[j].h<=ma;j++){
if(vis[i].x1==1&&vis[i].x2==1) break;
if(dp[i].x1==inf&&dp[i].x2==inf) continue;
if(j==n) {
if(vis[i].x1==0) ans=min(ans,dp[i].x1+a[i].h);
if(vis[i].x2==0) ans=min(ans,dp[i].x2+a[i].h);
}
if(a[j].x1<=a[i].x1 && a[i].x1<=a[j].x2&&vis[i].x1==0){//从左端点能下来
dp[j].x1=min(dp[i].x1+a[i].h-a[j].h+a[i].x1-a[j].x1,dp[j].x1);//到左端点的时间
dp[j].x2=min(dp[i].x1+a[i].h-a[j].h+a[j].x2-a[i].x1,dp[j].x2);
vis[i].x1=1;
}
if(a[j].x1<=a[i].x2 && a[i].x2<=a[j].x2&&vis[i].x2==0){
dp[j].x1=min(dp[i].x2+a[i].h-a[j].h+a[i].x2-a[j].x1,dp[j].x1);
dp[j].x2=min(dp[i].x2+a[i].h-a[j].h+a[j].x2-a[i].x2,dp[j].x2);
vis[i].x2=1;
}
//printf("%d %d %d %d\n",j,dp[j].x1,dp[j].x2,ans);
}
}
printf("%d\n",ans);
}
}原文:http://blog.csdn.net/lj94093/article/details/45500137