Help Jimmy (POJ 1661)

题解:这题由于N比较小,直接枚举i-1个平台即可。一开始根据H排序。DP[I][0..1],表示这个平台i左端点和右端点到地面的最小时间。只考虑左端点,右端点类似。

IF i左端点下面无线段
{
IF i的高度>maxh,DP[I][0]=MAXX;
ELSE DP[I][0]=0;
}

ELSE
{
IF i-k的高度>maxh, DP[I][0]=MAXX;
ELSE DP[I][0]=MIN(DP[K][0]+ABS(L[K]-L[I]),DP[K][1]+ABS(R
[K]-L[I]));
}

#include<cstdio>
#include<algorithm>
#define maxn 2000
#define maxx 29999999
using namespace std;
int flag,i,j,k,n,x0,y0,ans,maxh,t,m;
int f[maxn][2];
struct node{int l,r,h;}a[maxn];
bool cmp(const node&a,const node&b){return a.h>b.h;}
int min(int a,int b){return (a>b)?b:a;}
int main()
{
 scanf("%d",&t);
 for (k=1;k<=t;k++)
  {
  scanf("%d%d%d%d",&n,&x0,&y0,&maxh);n++;
  for (i=2;i<=n;i++) scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].h);
  a[1].l=x0;a[1].r=x0;a[1].h=y0;
  sort(a+1,a+n+1,cmp);
  for (i=n;i>=1;i--)
       {
       flag=0;
       for (j=i+1;j<=n;j++)
        if (a[j].l<=a[i].l&&a[j].r>=a[i].l){flag=1;break;}
       if (flag==1){
       if (a[i].h-a[j].h>maxh) f[i][0]=maxx;
            else { 
            f[i][0]=min(f[j][0]+a[i].h-a[j].h+a[i].l-a[j].l,f[j][1]+a[i].h-a[j].h+a[j].r-a[i].l);
                 }
                   }
              else {if (a[i].h>maxh) f[i][0]=maxx;else f[i][0]=a[i].h;}

       flag=0;
        for (j=i+1;j<=n;j++)
        if (a[j].l<=a[i].r&&a[j].r>=a[i].r){flag=1;break;}
       if (flag==1){
       if (a[i].h-a[j].h>maxh) f[i][1]=maxx;
            else { 
                f[i][1]=min(f[j][0]+a[i].h-a[j].h+a[i].r-a[j].l,f[j][1]+a[i].h-a[j].h+a[j].r-a[i].r);
                 }
                   } 
                        else {if (a[i].h>maxh) f[i][1]=maxx;
                               else f[i][1]=a[i].h;}

       }
     ans=min(f[1][0],f[1][1]);
  if (ans>=maxx) printf("-1\n");
              else printf("%d\n",ans);
  }
return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值