Help Jimmy POJ - 1661

Posted Jozky86

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Help Jimmy POJ - 1661相关的知识,希望对你有一定的参考价值。

Help Jimmy POJ - 1661

题意:

在这里插入图片描述

场景中包括多个长度和高度各不相同的平台。地面是最低的平台,高度为零,长度无限。

Jimmy老鼠在时刻0从高于所有平台的某处开始下落,它的下落速度始终为1米/秒。当Jimmy落到某个平台上时,游戏者选择让它向左还是向右跑,它跑动的速度也是1米/秒。当Jimmy跑到平台的边缘时,开始继续下落。Jimmy每次下落的高度不能超过MAX米,不然就会摔死,游戏也会结束。

设计一个程序,计算Jimmy到底地面时可能的最早时间。

题解:

设dp[i][0]:表示到第i个板子上的左侧所花时间
dp[i][1]:表示到第i个板子上的右侧所花时间
从第j个到第i个平台上,第j的高度要大于i(高度差不能超过MAX),从j下来分左右两个端点,需要保证左右端点都在i平台的范围内(这样才能落在平台上),且注意,满足上面两个情况仍然不足,因为有可能j被k挡住了,从j就无法到i上面,一个平台最多只能到达另一个平台,所以我们用数组st[j][0/1]表示从平台j出发,从左/右端点掉下去会到哪个板子,如果st = -1说明可以直接掉到当前平台
详细看代码

代码:

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1010;
int n,m,t,x,y,st[N][2];//st[i][0]标记第i块板子左端可以落到那个板子,st[i][1]就是右端
struct node
{
	int l,r,h;
}e[N];
ll f[N][2];
bool cmp(node a,node b)
{
	if(a.h==b.h) return a.l<b.l;//这里其实无所谓加不加
	return a.h>b.h;
}
int main()
{
	cin>>t;
	while(t--)
	{
		cin>>n>>x>>y>>m;
		for(int i=1;i<=n;i++)
		{
			int a,b,c;
			cin>>a>>b>>c;
			e[i]={a,b,c};
		}
		e[0]={x,x,y};
		sort(e+1,e+n+1,cmp);
		memset(st,-1,sizeof st);
		memset(f,0x3f,sizeof f);
		f[0][0]=f[0][1]=0;
		for(int i=1;i<=n;i++)
		{
			for(int j=0;j<i;j++)
			{
				if(e[j].h-e[i].h<=m)//条件1
				{
					if(e[j].l>=e[i].l&&e[j].l<=e[i].r)//条件2
					{
						if(st[j][0]==-1)//条件3
						{
							f[i][0]=min(f[i][0],f[j][0]+e[j].h-e[i].h+e[j].l-e[i].l);
							f[i][1]=min(f[i][1],f[j][0]+e[j].h-e[i].h+e[i].r-e[j].l);
							st[j][0]=i;
						}
					}
					if(e[j].r>=e[i].l&&e[j].r<=e[i].r)//条件2
					{
						if(st[j][1]==-1)//条件3
						{
							f[i][0]=min(f[i][0],f[j][1]+e[j].h-e[i].h+e[j].r-e[i].l);
							f[i][1]=min(f[i][1],f[j][1]+e[j].h-e[i].h+e[i].r-e[j].r);
							st[j][1]=i;
						}
					}
				}
			}
		}
		ll ans=0x3f3f3f3f3f3f3f3f;
		for(int i=0;i<=n;i++)
			if(e[i].h<=m)
			{
				if(st[i][0]==-1) ans=min(ans,f[i][0]+e[i].h);
				if(st[i][1]==-1) ans=min(ans,f[i][1]+e[i].h);
			}
		cout<<ans<<endl;
	}
	
}


这是我一开始写的wa代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define debug(a,b) printf("%s = %d\\n",a,b);
typedef long long ll;
using namespace std;

inline int read(){
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);
   return s*w;
}
const int maxn=2000;
struct node{
	int x1,x2,h;
}a[maxn]; 
bool cmp(node a,node b){
	return a.h>b.h;
}
int dp[maxn][3];
int main()
{
	int t;
	cin>>t;
	while(t--){
		memset(a,0,sizeof(a));
		int n=read(),x=read(),y=read(),MAX=read();
		for(int i=1;i<=n;i++){
			a[i].x1=read();
			a[i].x2=read();
			a[i].h=read();
		}
		a[0].x1=a[0].x2=x;a[0].h=y;
		sort(a+1,a+1+n,cmp);//从小到大 
		memset(dp,0x3f3f3f3f,sizeof(dp));	
		/*
		dp[i][0]表示到左侧的距离 
		dp[i][1]表示到右侧的距离 
		*/
		dp[0][0]=0;dp[0][1]=0; 
		for(int i=1;i<=n;i++){
			int l=a[i].x1,r=a[i].x2;
			for(int j=i-1;j>=0;j--){
				if(a[j].x2<=r&&a[j].x2>=l&&(a[j].h-a[i].h)<=MAX)//从第j个砖的右侧下来
				{
					l=a[j].x2;
					dp[i][0]=min(dp[i][0],dp[j][1]+(a[j].h-a[i].h)+(a[j].x2-a[i].x1)); 
					dp[i][1]=min(dp[i][1],dp[j][1]+(a[j].h-a[i].h)+(a[i].x2-a[j].x2)); 
				}
				if(a[j].x1>=l&&a[j].x1<=r&&(a[j].h-a[i].h)<=MAX)//从第i个砖的左测下来
				{
					r=a[j].x1;
					dp[i][0]=min(dp[i][0],dp[j][0]+(a[j].h-a[i].h)+(a[j].x1-a[i].x1));
					dp[i][1]=min(dp[i][1],dp[j][0]+(a[j].h-a[i].h)+(a[i].x2-a[j].x1));
				}
			}
		}
		int l=-0x3f,r=0x3f;
		for(int j=n;j>=0;j--){
			if(a[j].x2<=r&&a[j].x2>=l&&(a[j].h)<=MAX)
			{
				l=a[j].x2;
				dp[n+1][0]=min(dp[n+1][0],dp[j][1]+a[j].h);
				dp[n+1][1]=min(dp[n+1][1],dp[j][1]+a[j].h);
			}
			if(a[j].x1>=l&&a[j].x1<=r&&(a[j].h)<=MAX){
				r=a[j].x1;
				dp[n+1][0]=min(dp[n+1][0],dp[j][0]+a[j].h);
				dp[n+1][1]=min(dp[n+1][1],dp[j][0]+a[j].h);
			}
		} 
		cout<<min(dp[n+1][0],dp[n+1][1])<<endl;
	}
}

以上是关于Help Jimmy POJ - 1661的主要内容,如果未能解决你的问题,请参考以下文章

POJ 1661 Help Jimmy(二维DP)

POJ1661 Help Jimmy —— DP

Help Jimmy POJ - 1661

POJ 1661 Help Jimmy

POJ 1661 (Help Jimmy )

Help Jimmy POJ - 1661 dp