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相关推荐

  1. 动态规划训练19、最短路 [Help Jimmy POJ - 1661 ]

    Help Jimmy POJ - 1661 题意:大致是一个人从某个点开始下落,下落的速度是1m/s,然后在平台上的时候可以左右移动,移动的速度也是1m/s,但是这里有一个限制,就是说每次下落的距离不 ...

  2. POJ 1661 Help Jimmy(递推DP)

    思路: 1. 每个板子有左右两端, dp[i][0], dp[i][1] 分别记录左右端到地面的时间 2. 从下到上递推计算, 上一层的板子必然会落到下面的某一层板子上, 或者地面上 总结: 1. 计 ...

  3. POJ 1661 Help Jimmy

    传送门:http://poj.org/problem?id=1661 解题思路:其实吧,不难就是细节有点麻烦. 实现代码: #include <iostream> #include < ...

  4. 【POJ - 1661】Help Jimmy(记忆化搜索,dp)

    题干: Help Jimmy" 是在下图所示的场景上完成的游戏. 场景中包括多个长度和高度各不相同的平台.地面是最低的平台,高度为零,长度无限. Jimmy老鼠在时刻0从高于所有平台的某处开 ...

  5. POJ - 1661 Help Jimmy DP

    题目链接 题意:题意很明了,就是求从最高点最短多长时间到达地面,从板上的移动与空中下落的速度都是1: 做法:我们首先将所有的板子与起点按照,左.右端点,高度存起来,按照高度升序. 然后dp,设dp[i ...

  6. POJ 1661 Help Jimmy DP

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

  7. POJ 1661 DP

    Help Jimmy Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11071   Accepted: 3607 Descr ...

  8. [kuangbin带你飞]专题十二 基础DP1

    A - Max Sum Plus Plus (HDU 1024) 题意:将n个数取m段且不相交,求m段数字和最大值: dp[i][j]:前i个数字分成j段的最大值. 边界dp[0][0] = 0; d ...

  9. kuangbin带你飞专题合集

    题目列表 [kuangbin带你飞]专题一 简单搜索 [kuangbin带你飞]专题二 搜索进阶 [kuangbin带你飞]专题三 Dancing Links [kuangbin带你飞]专题四 最短路 ...

最新文章

  1. OpenCV之feature2d 模块. 2D特征框架(2)特征描述 使用FLANN进行特征点匹配 使用二维特征点(Features2D)和单映射(Homography)寻找已知物体 平面物体检测
  2. flarum论坛如何html,简约个人小清新论坛-Flarum的快速搭建方法
  3. org.apache.commons.io——FileUtils学习笔记
  4. C#与C/C++的交互zz
  5. 【华为云技术分享】如何做一个优秀软件-可扩展的架构,良好的编码,可信的过程
  6. jquery中防止和其他JS框架冲突的办法
  7. Wpe工作原理和教程-以传奇为列
  8. Linux进程间通信
  9. 再也不用花一天时间做ppt了
  10. 共识算法PBFT和Raft
  11. 旅游吧!我在这里 ——旅游相册POI搜索:找回你的足迹
  12. linux中引号的作用是什么意思,Linux中的双引号的作用
  13. android ndk 怎样调用第三方的so库文件。
  14. 计算机在化学中论文3000字,化学论文范文3000字_化学论文发表
  15. js 打开指定的浏览器_如何实现一个谷歌浏览器插件
  16. 微信H5公众号chooseImg上传图片
  17. Error:(63, 24) 错误: 枚举 switch case 标签必须为枚举常量的非限定名称
  18. 互联网金融:为什么贷前风控需要进行手机号码验证(联通、移动、电信)
  19. 机器学习小组知识点7:伯努利分布(Bernouli Distribution)
  20. Linux惊群效应之Nginx解决方案

热门文章

  1. 一滴水从高处落下来,会不会砸死人?
  2. 三角形中惊现叛徒!自己胖的像个球,却能成就世界上最快的赛车引擎......
  3. 北大清华团队编写!200多个科学实验+视频,和爸爸一起在家做
  4. MATLAB常用算法与应用实例分享来袭!
  5. 重磅来袭,2018 年 6 月编程语言排行榜
  6. 10分钟读懂人工智能、机器学习到底有什么关系
  7. 兄弟机cnc系统面板图解_FANUC软操作面板的应用介绍,真的太详细了
  8. cass字体_不动产 准备工作 第一步: 管理CASS码
  9. python数据整理_python数据类型整理
  10. apache weblogic ssl linux,apache基于ssl配置weblogic(完结篇)