POJ 1661 动态规划 Help Jimmy

动态规划,意思简洁明了。

排序,n^2做法。

每次检测可行的长条,最高的永远是起始点。

dp[i][0]表示第i个长条的左边下去最短的时间。

dp[i][1]表示第i个长条的右边下去最短的时间。

#include <cstdio>
#include <iostream>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <cstring>
#include <string>

using namespace std;
int n;
int INF=2000000;
struct Edge
{
    int left,right,high;
} a[1010];
int dp[1010][2];
int cmp(Edge a,Edge b)
{
    return a.high>b.high;
}
int main()
{
    int T;
    scanf ("%d",&T);
    while (T--)
    {
        scanf ("%d",&n);
        int xx,yy,max_high,i,j;
        scanf ("%d%d%d",&xx,&yy,&max_high);
        a[0].left=xx;
        a[0].right=xx;
        a[0].high=yy;
        for (i=1; i<=n; i++)
            scanf ("%d%d%d",&a[i].left,&a[i].right,&a[i].high);
        sort(a+1,a+n+1,cmp);
        dp[n][0]=a[n].high;
        dp[n][1]=a[n].high;
        for (i=n-1; i>=0; i--)
        {
            for (j=i+1; j<=n; j++)
                if (a[j].left<=a[i].left&&a[j].right>=a[i].left)
                    break;
            if (j<=n)
            {
                if (a[i].high-a[j].high>max_high) dp[i][0]=INF;
                else
                {
                    int t1=a[i].left-a[j].left+a[i].high-a[j].high+dp[j][0];
                    int t2=a[j].right-a[i].left+a[i].high-a[j].high+dp[j][1];
                    dp[i][0]=min(t1,t2);
                }
            }
            else
            {
                if (a[i].high>max_high) dp[i][0]=INF;
                else dp[i][0]=a[i].high;
            }

for (j=i+1; j<=n; j++)
                if (a[j].left<=a[i].right&&a[j].right>=a[i].right)
                    break;
            if (j<=n)
            {
                if (a[i].high-a[j].high>max_high) dp[i][1]=INF;
                else
                {
                    int t1=a[i].right-a[j].left+a[i].high-a[j].high+dp[j][0];
                    int t2=a[j].right-a[i].right+a[i].high-a[j].high+dp[j][1];
                    dp[i][1]=min(t1,t2);
                }
            }
            else
            {
                if (a[i].high>max_high) dp[i][1]=INF;
                else dp[i][1]=a[i].high;
            }
        }
        printf ("%d\n",min(dp[0][0],dp[0][1]));
    }
    return 0;
}

时间: 2024-10-23 23:26:38

POJ 1661 动态规划 Help Jimmy的相关文章

M - Help Jimmy POJ 1661 ( 动态规划 )

M - Help Jimmy Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u Submit Status Practice POJ 1661 Description "Help Jimmy" 是在下图所示的场景上完成的游戏. 场景中包括多个长度和高度各不相同的平台.地面是最低的平台,高度为零,长度无限. Jimmy老鼠在时刻0从高于所有平台的某处开始下落,它的下落速度始终为1米/秒.当Ji

POJ 1661 (Help Jimmy )

Help Jimmy Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 13669   Accepted: 4541 Description "Help Jimmy" 是在下图所示的场景上完成的游戏. 场景中包括多个长度和高度各不相同的平台.地面是最低的平台,高度为零,长度无限. Jimmy老鼠在时刻0从高于所有平台的某处开始下落,它的下落速度始终为1米/秒.当Jimmy落到某个平台上时,游戏者选择让它向左还是向右

[2016-03-29][POJ][1661][]Help Jimmy]

时间:2016-03-29 21:36:50 星期二 题目编号:[2016-03-29][POJ][1661][]Help Jimmy] #include <algorithm> #include <cstring> #include <cstdio> using namespace std; int n,x,y,maxh; struct Plat{ int l,r,h; bool operator < (const Plat & a)const{ ret

(动规 或 最短路)Help Jimmy(poj 1661)

http://poj.org/problem?id=1661 Description "Help Jimmy" 是在下图所示的场景上完成的游戏. 场景中包括多个长度和高度各不相同的平台.地面是最低的平台,高度为零,长度无限. Jimmy老鼠在时刻0从高于所有平台的某处开始下落,它的下落速度始终为1米/秒.当Jimmy落到某个平台上时,游戏者选择让它向左还是向右跑,它跑动的速度也是1米/秒.当Jimmy跑到平台的边缘时,开始继续下落.Jimmy每次下落的高度不能超过MAX米,不然就会摔死

poj 1458 动态规划DP

//  poj 1458  zoj 1733  最长公共子序列  DP #include <iostream>#include <string.h>#define N 1005using namespace std ;char  s1[N],s2[N];   int dp[N][N];int max(int a,int b)   {    return a>b ? a : b ;  }void f(int n,int m){   int i,j;    for (i=0; i

POJ 1661 Help Jimmy(二维DP)

题目链接:http://poj.org/problem?id=1661 题目大意: 如图包括多个长度和高度各不相同的平台.地面是最低的平台,高度为零,长度无限. Jimmy老鼠在时刻0从高于所有平台的某处(高H处)开始下落,它的下落速度始终为1米/秒.当Jimmy落到某个平台上时,游戏者选择让它向左还是向右跑,它跑动的速度也是1米/秒.当Jimmy跑到平台的边缘时,开始继续下落.Jimmy每次下落的高度不能超过MAX米,不然就会摔死,游戏也会结束. 设计一个程序,计算Jimmy到底地面时可能的最

poj 1661 Help Jimmy(记忆化搜索)

题目链接:http://poj.org/problem?id=1661 一道还可以的记忆化搜索题,主要是要想到如何设dp,记忆化搜索是避免递归过程中的重复求值,所以要得到dp必须知道如何递归 由于这是个可以左右移动的所以递归过程肯定设计左右所以dp的一维为从左边下或者从右边下,而且和层数有关所以另一维为层数 于是便可以得到dp[count][flag],flag=1表示count层从左边下要多久,flag=0表示count层从右边下要多久.然后就是dfs的递归 过程 #include <iost

POJ 1661 Help Jimmy(DP,注意边界)

Help Jimmy Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9399   Accepted: 3025 Description "Help Jimmy" 是在下图所示的场景上完成的游戏. 场景中包括多个长度和高度各不相同的平台.地面是最低的平台,高度为零,长度无限. Jimmy老鼠在时刻0从高于所有平台的某处开始下落,它的下落速度始终为1米/秒.当Jimmy落到某个平台上时,游戏者选择让它向左还是向右跑

POJ 1661 Help Jimmy 最短路

题目大意:POJ少有的中文题,自己看吧,题意挺简单的. 思路:这本是一道DP的题,被我用最短路水过去了,没想到还0ms. 建图的思路比较简单,就是实现起来比较费劲.把每个东西按高度排序,从上到下n^2的枚举左右端点,然后满足条件的连边,边权为高度差+水平距离差. 然后跑SPFA就行了.注意一下Jimmy直接能跳到地面上的情况,这wa了一次. CODE: #include <queue> #include <cstdio> #include <cstring> #incl