POJ 1661 简单dp

要求:老鼠在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]));
  }	
} 

猜你喜欢

转载自blog.csdn.net/Irving0323/article/details/84727472