先前用递推的方法0msAC。进来搞动态规划,刚看到题时想到二叉树,用递归实现了一下,TML。改成dp,16msAC。
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
#define N 1005
#define oo 0x7fffffff
using namespace std;
struct pai
{
int l,r,h,minl,minr;
};
pai all[N];
int cmp(const void *a,const void *b)
{
return (*(pai *)b).h - (*(pai *)a).h;
}
int main()
{
int t,i,j,k,n,m,p,si,sj,Max;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d%d",&n,&si,&sj,&Max);
for(i = 1;i <= n;i++)
{
all[i].minl = all[i].minr = oo;
scanf("%d%d%d",&all[i].l,&all[i].r,&all[i].h);
}
qsort(all+1,n,sizeof(all[0]),cmp);
for(i = 1;i <= n;i++)//去掉高于下降点和部分不可到的平台。
{
if(all[i].h < sj&&all[i].l <= si&&all[i].r>=si)
break;
}
k = i-1;
all[k].l = all[k].r = si;//将开始下降点视为一个平台。便于统一处理。
all[k].h = sj;
all[k].minl = all[k].minr = 0;
for(i = k;i <= n;i++)
{
if(all[i].minl < oo)//跳过不可到达的点
{
for(j = i+1;j <= n;j++)//记录左边沿
{
if(all[i].h -all[j].h<=Max&&all[j].l <= all[i].l&&all[j].r >=all[i].l)
{
p = all[i].minl + all[i].h - all[j].h + all[i].l - all[j].l;
if(all[j].minl > p)
all[j].minl = p;
p = all[i].minl + all[i].h - all[j].h + all[j].r - all[i].l;
if(all[j].minr > p)
all[j].minr = p;
all[i].minl = oo;//覆盖掉不可一步到达地面的点
break;
}
}
for(j = i+1;j <= n;j++)//记录右边沿
{
if(all[i].h -all[j].h<=Max&&all[j].l <= all[i].r&&all[j].r >=all[i].r)
{
p = all[i].minr + all[i].h - all[j].h + all[i].r - all[j].l;
if(all[j].minl > p)
all[j].minl = p;
p = all[i].minr + all[i].h - all[j].h + all[j].r - all[i].r;
if(all[j].minr > p)
all[j].minr = p;
all[i].minr = oo;//覆盖掉不可一步到达地面的点
break;
}
}
}
}
int MM = oo;
for(i = k;i <= n;i++)
{
if(all[i].h <= Max)
{
if(all[i].minl != oo && all[i].minl + all[i].h < MM)
MM = all[i].minl + all[i].h;
if(all[i].minr != oo && all[i].minr + all[i].h < MM)
MM = all[i].minr + all[i].h;
}
}
printf("%d\n",MM);
}
return 0;
}
顺便把0ms的代码也贴出来吧。
#include <cstring>
#include <stdio.h>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;
struct pai
{
int l;
int r;
int h;
};
pai all[1005];
int cmp(const void *a,const void *b)
{
return (*(pai *)b).h -(*(pai *)a).h;
}
int luo[40005][3];
int main()
{
int i,j,t,n,m,p,q,flag,x,y,temp,Max,Min,LMin,RMin;
scanf("%d",&t);
while (t--)
{
scanf("%d%d%d%d",&n,&x,&y,&Max);
all[0].l = all[0].r = x + 20000;
all[0].h = y;
for(i = 1;i <= n;i++)
{
scanf("%d%d%d",&all[i].l,&all[i].r,&all[i].h);
all[i].l += 20000;
all[i].r += 20000;
}
qsort(all,n+1,sizeof(all[0]),cmp);
memset(luo,0,sizeof(luo));
luo[x+20000][0] = 1;
luo[x+20000][1] = 0;
luo[x+20000][2] = y;
for(i = 1;i<n+1;i++)
{
LMin = RMin = 99999999;
flag = 0;
for(j = all[i].l;j <= all[i].r;j++)
{
if (luo[j][0]&&luo[j][2] - all[i].h <= Max)
{
temp = luo[j][1] + luo[j][2] - all[i].h + j - all[i].l;
if(LMin > temp)
LMin = temp;
temp = luo[j][1] + luo[j][2] - all[i].h + all[i].r - j;
if (RMin > temp)
RMin = temp;
luo[j][0] = 0;
flag = 1;
}
}
if(flag)
{
luo[all[i].l][0] = luo[all[i].r][0] = 1;
luo[all[i].l][1] = LMin;
luo[all[i].r][1] = RMin;
luo[all[i].l][2] = luo[all[i].r][2] = all[i].h;
}
}
Min = 99999999;
for(i = 0;i < 40003;i++)
{
if (luo[i][0]&&luo[i][2]<=Max)
{
if (Min > luo[i][1] + luo[i][2])
Min = luo[i][1] + luo[i][2];
}
}
printf("%d\n",Min);
}
return 0;
}