POJ 1661 Help Jimmy

来源:互联网 发布:雅马哈f310知乎 编辑:程序博客网 时间:2024/06/10 16:28

Description

"Help Jimmy" 是在下图所示的场景上完成的游戏。 

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

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

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

Input

第一行是测试数据的组数t(0 <= t <= 20)。每组测试数据的第一行是四个整数N,X,Y,MAX,用空格分隔。N是平台的数目(不包括地面),X和Y是Jimmy开始下落的位置的横竖坐标,MAX是一次下落的最大高度。接下来的N行每行描述一个平台,包括三个整数,X1[i],X2[i]和H[i]。H[i]表示平台的高度,X1[i]和X2[i]表示平台左右端点的横坐标。1 <= N <= 1000,-20000 <= X, X1[i], X2[i] <= 20000,0 < H[i] < Y <= 20000(i = 1..N)。所有坐标的单位都是米。 

Jimmy的大小和平台的厚度均忽略不计。如果Jimmy恰好落在某个平台的边缘,被视为落在平台上。所有的平台均不重叠或相连。测试数据保证问题一定有解。 

Output

对输入的每组测试数据,输出一个整数,Jimmy到底地面时可能的最早时间。

Sample Input

13 8 17 200 10 80 10 134 14 3

Sample Output

23


将给定的平台按照高度依次排序,每一个平台都有向左的时间和向右的时间,当然并不是时间最短的就一定是最优,因为如果某一个方向下的平台高度超过规定高度则是不可行的方向。这样从小鼠出发点开始自上往下按层次寻找每个平台的最优时间,先查找该平台的某方向是否可行,可行则选取最短时间,否则该路不通(即设置最大值),dp[i][k]表示第i平台方向k的最短时间,不难得出转移方程dp[i][k]=min(dp[j][0]+s[i].h-s[j].h+s[i].x[k]-s[j].x[0],dp[j][1]+s[i].h-s[j].h+s[j].x[1]-s[i].x[k]),具体思路见注释:



#include <iostream>#include <algorithm>#include <cstring>using namespace std;const int INF=(1<<30);struct platform{int x[2],h;void setValue(int a,int b,int c){x[0]=a;x[1]=b;h=c;}bool operator < (const platform a)const{return h>a.h;//高的在前}}s[1010];int dp[1010][2];int main(){ios::sync_with_stdio(false);int t;cin>>t;while(t--){memset(dp,0,sizeof(dp));int n,x,y,maxn;cin>>n>>x>>y>>maxn;s[0].setValue(x,x,y);//将小鼠位置初始化(算作一个平台)for(int i=1;i<=n;i++)cin>>s[i].x[0]>>s[i].x[1]>>s[i].h;sort(s,s+n+1);//这里一开始少排了一个,无限WA。。。一定记住这是n+1个元素。。。dp[n][0]=dp[n][1]=s[n].h;//最下面的平台的最短时间为此平台高度for(int i=n-1,j;i>=0;i--){for(int k=0;k<2;k++){for(j=i+1;j<=n;j++)//向下检查该平台某一端下是否有平台(k=0表示左,k=1表示右)if(s[i].x[k]>=s[j].x[0]&&s[i].x[k]<=s[j].x[1])break;if(j<=n)//如果某端点下有平台{if(s[i].h-s[j].h>maxn)//如果差值超过限定高度dp[i][k]=INF;//设置一个很大的数else//否则选取最小时间dp[i][k]=min(dp[j][0]+s[i].h-s[j].h+s[i].x[k]-s[j].x[0],dp[j][1]+s[i].h-s[j].h+s[j].x[1]-s[i].x[k]);}else//如果没有平台,则说明可直接通过该端到达地面{if(s[i].h>maxn)//如果到地面距离超过限定dp[i][k]=INF;else//可以安全到达地面dp[i][k]=s[i].h;}}}cout<<dp[0][0]<<endl;}return 0;}



0 0
原创粉丝点击