要求:老鼠在0时刻从位置(x,y)下落,x是横坐标,y是纵坐标(即高度),下落速度是1m/s,有若干个与地面平行的平台悬在空中,平台的左右端点和高度确定,不存在重叠的平台。老鼠若落在平台的端点上,视作落在平台上。老鼠下落高度不能超过maxh,求老鼠落地的最短时间。
方法:dp题 注意确定好状态以好写
1.这道题vj上没法交,只能在poj上交了,截个图记录一下。
2.先把平台按高度从低到大排序。
3.dp[i][0]表示从第i个平台的左端点下落开始计时,落地的最短时间。
dp[i][1]表示从第i个平台的右端点下落开始计时,落地的最短时间。
状态方程没啥难度,下落高度 + min(向左走到下一个左端点的状态,向右走到下一个右端点的状态)。
主要是状态,状态分析不对很麻烦。
4.地面和起点都看作平台。
5.代码的状态为dp[i][0]表示从第i个平台的左端点开始计时,落地的最短时间。少了下落让我写了好久。。。。。。
扫描二维码关注公众号,回复:
4808068 查看本文章
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
int n,x,y,maxh;
int dp[1005][2];
//dp[i][0]表示第i个平台的左端点为起点走到地面的最短时间
//dp[i][1]表示第i个平台向右端点为起点走到地面的最短时间
struct node
{
int x1,x2,h;
}flat[1005];
bool cmp(node a,node b)
{
return a.h<b.h;
}
void cal()
{
int i , j ;
int templ , tempr ;
int leni ;
int deltah , li , ri , lj , rj ;
int ll , lr , rl , rr ;
int hl , hr ;
memset(dp , inf , sizeof(dp)) ;
dp[0][0] = dp[0][1] = 0;//地面到地面的时间为0
for(i = 1 ; i <= n + 1 ; i ++)
{
templ = -1 , tempr = -1 ;
leni = flat[i].x2 - flat[i].x1 ;
for(j = i - 1 ; j >= 0 ; j --)
{
deltah = flat[i].h - flat[j].h ;
li = flat[i].x1 , ri = flat[i].x2 ;
lj = flat[j].x1 , rj = flat[j].x2 ;
if(deltah > 0 && deltah <= maxh)
{
if(lj <= li && li <= rj && templ == -1)
{
templ = j ;
hl = deltah ;
ll = flat[i].x1 - flat[j].x1 ;
lr = flat[j].x2 - flat[i].x1 ;
}
if(lj <= ri && ri <= rj && tempr == -1)
{
tempr = j;
hr = deltah ;
rl = flat[i].x2 - flat[j].x1 ;
rr = flat[j].x2 - flat[i].x2 ;
}
}
}
if(templ == 0)
{
dp[i][0] = min(dp[i][0] , flat[i].h);
dp[i][1] = min(dp[i][1] , hl + leni);
}
if(templ > 0)
{
dp[i][0] = min(dp[i][0] , hl + ll + dp[templ][0]);
dp[i][0] = min(dp[i][0] , hl + lr + dp[templ][1]);
dp[i][1] = min(dp[i][1] , hl + leni + ll + dp[templ][0]);
dp[i][1] = min(dp[i][1] , hl + leni + lr + dp[templ][1]);
}
if(tempr == 0)
{
dp[i][0] = min(dp[i][0] , hr + leni);
dp[i][1] = min(dp[i][1] , hr);
}
if(tempr > 0)
{
dp[i][0] = min(dp[i][0] , hr + leni + rl + dp[tempr][0]);
dp[i][0] = min(dp[i][0] , hr + leni + rr + dp[tempr][1]);
dp[i][1] = min(dp[i][1] , hr + rl + dp[tempr][0]);
dp[i][1] = min(dp[i][1] , hr + rr + dp[tempr][1]);
}
}
}
int main()
{
int t,i;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d%d",&n,&x,&y,&maxh);
flat[0].x1=x,flat[0].x2=x,flat[0].h=y;
for(i=1;i<=n;i++)
scanf("%d%d%d",&flat[i].x1,&flat[i].x2,&flat[i].h);
flat[n+1].x1=-20000,flat[n+1].x2=20000,flat[n+1].h=0;
sort(flat,flat+n+2,cmp);
cal();
printf("%d\n",min(dp[n+1][0] , dp[n+1][1]));
}
}