两种解法
一:记忆化搜索 写法其实很多
一个搜索题一般写法很多 理清思路 各种边界处理好就行 不要一会觉得这样行 过一会觉得那样好 反而搞乱了思路
using namespace std;
struct node
{
int l;
int r;
int h;
};
node line[1010];
int book[1010],left[1010],right[1010];
int n,pos,hh,lim;
bool cmp(node n1,node n2)
{
return n1.h>n2.h;
}
void dfs(int cur)
{
int i;
for(i=cur+1;i<=n+1;i++)
{
if(line[i].l<=line[cur].l&&line[cur].l<=line[i].r&&line[cur].h-line[i].h<=lim)
{
if(!book[i])
{
dfs(i);
}
if(i==n+1)
{
left[cur]=line[cur].h-line[i].h;
}
else
{
left[cur]=min(left[i]+line[cur].l-line[i].l,right[i]+line[i].r-line[cur].l)+(line[cur].h-line[i].h);
}
break;
}
}
for(i=cur+1;i<=n+1;i++)
{
if(line[i].l<=line[cur].r&&line[cur].r<=line[i].r&&line[cur].h-line[i].h<=lim)
{
if(!book[i])
{
dfs(i);
}
if(i==n+1)
{
right[cur]=line[cur].h-line[i].h;
}
else
{
right[cur]=min(left[i]+line[cur].r-line[i].l,right[i]+line[i].r-line[cur].r)+(line[cur].h-line[i].h);
}
break;
}
}
book[cur]=1;
return;
}
int main()
{
int t,i,p,ans,tem;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d%d",&n,&pos,&hh,&lim);
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&line[i].l,&line[i].r,&line[i].h);
}
sort(line+1,line+n+1,cmp);
line[n+1].l=-20000,line[n+1].r=20000,line[n+1].h=0;
memset(book,0,sizeof(book));
memset(left,0x3f,sizeof(left));
memset(right,0x3f,sizeof(right));
book[n+1]=1,left[n+1]=0,right[n+1]=0;
for(i=1;i<=n+1;i++)
{
if(line[i].l<=pos&&pos<=line[i].r)
{
p=i,ans=hh-line[i].h;
break;
}
}
if(p!=n+1)
{
dfs(p);
ans+=min(pos-line[p].l+left[p],line[p].r-pos+right[p]);
}
printf("%d\n",ans);
}
return 0;
}
二:DP
using namespace std;
struct node
{
int l;
int r;
int h;
};
struct node line[1001];
int dp[1001][2];
int n,sx,sy,lim;
int cmp(node n1,node n2)
{
return n1.h>n2.h;
}
int main()
{
int t,i,j,flagl,flagr,ans;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d%d",&n,&sx,&sy,&lim);
memset(dp,0,sizeof(int));
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&line[i].l,&line[i].r,&line[i].h);
dp[i][0]=dp[i][1]=N;
}
line[0].l=sx,line[0].r=sx,line[0].h=sy;
line[n+1].l=-20000,line[n+1].r=20000,line[n+1].h=0;
sort(line,line+n+2,cmp);
dp[0][0]=dp[0][1]=0;
ans=N;
for(i=0;i<=n;i++)
{
flagl=1,flagr=1;
for(j=i+1;j<=n+1;j++)
{
if(flagl==0&&flagr==0||line[i].h-line[j].h>lim)
{
break;
}
if(line[j].l<=line[i].l&&line[i].l<=line[j].r&&line[i].h!=line[j].h&&flagl==1)
{
flagl=0;
if(j==n+1)
{
ans=min(ans,dp[i][0]);
}
else
{
dp[j][0]=min(line[i].l-line[j].l+dp[i][0],dp[j][0]);
dp[j][1]=min(line[j].r-line[i].l+dp[i][0],dp[j][1]);
}
}
if(line[j].l<=line[i].r&&line[i].r<=line[j].r&&flagr==1)
{
flagr=0;
if(j==n+1)
{
ans=min(ans,dp[i][1]);
}
else
{
dp[j][0] = min(line[i].r-line[j].l+dp[i][1],dp[j][0]);
dp[j][1] = min(line[j].r-line[i].r+dp[i][1],dp[j][1]);
}
}
}
if(flagl==0)
{
if(line[i].h<=lim) dp[i][0]=line[i].h;
else dp[i][0]=N;
}
if(flagr==0)
{
if(line[i].h<=lim) dp[i][1]=line[i].h;
else dp[i][0]=N;
}
}
printf("%d\n",ans+sy);
}
return 0;
}