标签:dp
把平台按高度排序,从前面的平台开始往下找,找到最近的一个平台,记录下来的点,以后不再能从该点下来了,因为小人不能穿过平台直接下落,最后到达地面的时候特殊处理一下
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); } }
标签:dp
原文地址:http://blog.csdn.net/lj94093/article/details/45500137