POJ 1661 Help Jimmy

/*96655 ‘s source code for M
Memory: 8604 KB        Time: 63 MS
Language: G++        Result: Accepted
*/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
short x[1006],y[1005],h[1005];
short xx[2005],hh[1005],xcnt,hcnt,d,ww,f;
int dp[1003][2003];
bool cmp(int a,int b)
{
    return a>b;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,bb,cc,m;
        scanf("%d%d%d%d",&n,&bb,&cc,&m);
        xcnt=hcnt=0;
        for(int i=1; i<=n; ++i)
        {
            scanf("%d%d%d",&x[i],&y[i],&h[i]);
            xx[xcnt++]=x[i];
            xx[xcnt++]=y[i];
            hh[hcnt++]=h[i];
        }
        xx[xcnt++]=bb;
        hh[hcnt++]=0;
        sort(xx,xx+xcnt);
        sort(hh,hh+hcnt,cmp);
        d=1;
        for(int i=1; i<xcnt; i++)
            if(xx[i]!=xx[i-1])xx[d++]=xx[i];
        xcnt=d,d=1;
        for(int i=1; i<hcnt; i++)
            if(hh[i]!=hh[i-1])hh[d++]=hh[i];
        hcnt=d;
        vector<int>a[hcnt+1];
        memset(dp,-1,sizeof(dp));
        int ans=0x3f3f3f3f;
        for(int i=0; i<xcnt; i++)
            dp[hcnt-1][i]=ans;
        for(int i=1; i<=n; i++)
        {
            int id;
            for(int j=0; j<hcnt; j++)
                if(h[i]==hh[j])
                {
                    id=j;
                    break;
                }
            int s=lower_bound(xx,xx+xcnt,x[i])-xx;
            int t=lower_bound(xx,xx+xcnt,y[i])-xx;
            a[id].push_back(s);
            a[id].push_back(t);
            for(int j=s; j<=t; ++j)
                dp[id][j]=ans;
        }
        f=lower_bound(xx,xx+xcnt,bb)-xx;
        for(int i=0; i<hcnt; i++)
        {
            if(dp[i][f]!=-1)
            {
                dp[i][f]=cc-hh[i];
                ww=i;
                break;
            }
        }
        for(int i=ww; i<hcnt-1; ++i)
        {
            for(int j=0; j<xcnt; j++)
            {
                if(dp[i][j]<ans&&dp[i][j]!=-1)
                {
                    int s,t;
                    for(int k=1;k<a[i].size();k+=2)
                    {
                        if(a[i][k-1]<=j&&a[i][k]>=j)
                        {
                            s=a[i][k-1];
                            t=a[i][k];
                            break;
                        }
                    }
                    int l=xx[j]-xx[s],r=xx[t]-xx[j];
                    dp[i][s]=min(dp[i][s],dp[i][j]+l);
                    dp[i][t]=min(dp[i][t],dp[i][j]+r);

                }
            }
            for(int j=0; j<a[i].size(); ++j)
            {
                int p=a[i][j];
                if(dp[i][p]!=-1&&dp[i][p]<ans)
                {
                    for(int k=i+1; k<hcnt&&hh[i]-hh[k]<=m; k++)
                        if(dp[k][p]!=-1)
                        {
                            dp[k][p]=min(dp[k][p],dp[i][p]+hh[i]-hh[k]);
                            break;
                        }
                }
            }
        }
        for(int i=0; i<xcnt; i++)
            ans=min(ans,dp[hcnt-1][i]);
        printf("%d\n",ans);
    }
    return 0;
}

时间: 2024-10-06 00:40:52

POJ 1661 Help 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

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

POJ 1661 Help Jimmy DP

题目思路:状态转移方程很好推出,值得注意的是要分别判断是否能从一个平台的某侧移动到另一平台,也就是说要判断过一个平台的左端点或右端点做垂线,看这条垂线是否经过其他平台. #include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h> #include<iostream> #include<algorithm> #define INF 0x3FFFFFFF

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

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

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

POJ 1661 (Help Jimmy )

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