POJ 1661 Help Jimmy(二维DP)
题目链接:http://poj.org/problem?id=1661
题目大意:
如图包括多个长度和高度各不相同的平台。地面是最低的平台,高度为零,长度无限。
Jimmy老鼠在时刻0从高于所有平台的某处(高H处)开始下落,它的下落速度始终为1米/秒。当Jimmy落到某个平台上时,游戏者选择让它向左还是向右跑,它跑动的速度也是1米/秒。当Jimmy跑到平台的边缘时,开始继续下落。Jimmy每次下落的高度不能超过MAX米,不然就会摔死,游戏也会结束。
设计一个程序,计算Jimmy到底地面时可能的最早时间。
解题思路:根据题意易得无论如何都要下落H的高度,所以可以不用计算下落高度所需时间,直接计算水平走的最短时间最后加上高度即可,按平台高度从高到低排序,建立二维数组,dp[i][0]表示第i个平台往左走到达地面的最短水平时间,dp[i][1]表示第i个平台往右走到达地面的最短水平时间,于是有状态转移方程:
dp[i][0]=min(dp[j][0]+a[i].x1-a[j].x1,dp[j][1]+a[j].x2-a[i].x1), j是i左边下面的落点平台编号。
dp[i][1]=min(dp[j][1]+a[j].x2-a[i].x2,dp[j][0]+a[i].x2-a[j].x1),j是i右边下面的落点平台编号。
所以直接自底向上递推,每次往左或往右找到第一个落点平台计算最少时间,最后推到i=0(起始点)就可以了。
要注意一下①初始化dp为inf,dp[0][1]和dp[0][0]也要初始化为inf。
②找到第一个可掉落的平台计算之后,就break,不然会把下面几个平台都算进去。
③判断当找不到落点平台时,可能有三种情况:
1)所在平台高度小于等于MAX,但下面没有平台
2)下面有平台,但两平台高度差大于MAX
3)下面没有平台,且所在平台高度大于MAX
特判情况1),此时dp[i][0](或dp[i][1])为0
代码:
- #include<cstdio>
- #include<algorithm>
- using namespace std;
- const int N=1e3+;
- const int inf=<<;
- struct node{
- int x1,x2,h;
- }a[N];
- int dp[N][];//从第i层0往左,1往右
- bool cmp(node a,node b){
- return a.h>b.h;
- }
- int main(){
- int T;
- scanf("%d",&T);
- while(T--){
- int n,X,H,MAX;
- scanf("%d%d%d%d",&n,&X,&H,&MAX);
- for(int i=;i<=n;i++){
- scanf("%d%d%d",&a[i].x1,&a[i].x2,&a[i].h);
- dp[i][]=dp[i][]=inf;
- }
- sort(a+,a++n,cmp);
- //将起始点也当成一个平台
- a[].h=H;
- a[].x1=a[].x2=X;
- dp[n][]=dp[n][]=;
- dp[][]=dp[][]=inf;
- //自底向上推
- for(int i=n-;i>=;i--){
- //往左走
- for(int j=i+;j<=n;j++){
- if(a[i].h-a[j].h<=MAX){
- if(a[j].x1<=a[i].x1&&a[j].x2>=a[i].x1){
- dp[i][]=min(dp[j][]+a[i].x1-a[j].x1,dp[j][]+a[j].x2-a[i].x1);
- break;
- }
- }
- }
- //下面没平台且里地面高度不超过MAX
- if(a[i].h<=MAX&&dp[i][]==inf)
- dp[i][]=;
- //往右走
- for(int j=i+;j<=n;j++) {
- if(a[i].h-a[j].h<=MAX){
- if(a[j].x2>=a[i].x2&&a[j].x1<=a[i].x2){
- dp[i][]=min(dp[j][]+a[j].x2-a[i].x2,dp[j][]+a[i].x2-a[j].x1);
- break;
- }
- }
- }
- if(a[i].h<=MAX&&dp[i][]==inf)
- dp[i][]=;
- }
- printf("%d\n",min(dp[][],dp[][])+H);
- }
- return ;
- }
POJ 1661 Help Jimmy(二维DP)的更多相关文章
- POJ 1661 Help Jimmy(递推DP)
思路: 1. 每个板子有左右两端, dp[i][0], dp[i][1] 分别记录左右端到地面的时间 2. 从下到上递推计算, 上一层的板子必然会落到下面的某一层板子上, 或者地面上 总结: 1. 计 ...
- POJ 1661 Help Jimmy(C)动态规划
没刷过 POJ,这题是论坛有人问的,我才看看. 我发现 POJ 注册很奇怪,账号总是登不上去,弄的我还注册两个.Emmm 首次体验很差,还好我不在 POJ 刷题. 题目链接:POJ 1661 Help ...
- 洛谷p1732 活蹦乱跳的香穗子 二维DP
今天不BB了,直接帖原题吧 地址>>https://www.luogu.org/problem/show?pid=1732<< 题目描述 香穗子在田野上调蘑菇!她跳啊跳,发现 ...
- HDU - 2159 FATE(二维dp之01背包问题)
题目: 思路: 二维dp,完全背包,状态转移方程dp[i][z] = max(dp[i][z], dp[i-1][z-a[j]]+b[j]),dp[i][z]表示在杀i个怪,消耗z个容忍度的情况下 ...
- 传纸条 NOIP2008 洛谷1006 二维dp
二维dp 扯淡 一道比较基本的入门难度的二维dp,类似于那道方格取数,不过走过一次的点下次不能再走(看提交记录里面好像走过一次的加一次a[i][j]的也AC了,,),我记得当年那道方格取数死活听不懂, ...
- 洛谷P1048 采药 二维dp化一维
题目描述 辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师.为此,他想拜附近最有威望的医师为师.医师为了判断他的资质,给他出了一个难题.医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个 ...
- 关于二维DP————站上巨人的肩膀
意匠惨淡经营中ing, 语不惊人死不休........ 前几天学了DP,做了个简单的整理,记录了关于DP的一些概念之类的,今天记录一下刚学的一个类型 ----关于二维DP 那建立二维数组主要是干嘛用的 ...
- poj 2155:Matrix(二维线段树,矩阵取反,好题)
Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 17880 Accepted: 6709 Descripti ...
- POJ 2155 Matrix (二维线段树)
Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 17226 Accepted: 6461 Descripti ...
随机推荐
- Ajax+Js局部刷新
通过 AJAX,JavaScript 可使用 JavaScript 的 XMLHttpRequest 对象来直接与服务器进行通信.通过这个对象, JavaScript 可在不重载页面的情况与 Web ...
- 【BZOJ1566】【NOI2009】管道取珠(动态规划)
[BZOJ1566][NOI2009]管道取珠(动态规划) 题面 BZOJ 题解 蛤?只有两档部分分.一脸不爽.jpg 第一档?爆搜,这么显然,爆搜+状压最后统计一下就好了 #include<i ...
- python基础----模块、包
一 模块 ...
- Java之基础20160806
注意这里介绍的JAVA基础是指你对C语言已经比较熟练或者有一定基础了,再学习如下这知识就会比较快. 1.JAVA也是从MAIN开始执行,但是要先定义类,文件名要与类名一致并且类名首字母要大写,同时JA ...
- 折腾到死:matlab7.0 安装
matlab7.0应该是2004年的东西了吧,装起来相当费劲!为什么不用更高的版本呢?其实我也想,之前安装的2013a安装包就5个多G,安装完之后就十多个G了.我习惯将软件安装到C盘,可怜我那100G ...
- libiop网络库数据结构和基础知识
最近朋友推荐,学习了libiop这个网络库,作者封装的很全面,代码很简洁 适合初学者学习基于事件驱动的网络io 先看看iop_def.h, 这里面定义了常用的数据结构 tag_iop_base_t 主 ...
- 题解【bzoj3240 [NOI2013]矩阵游戏】
挖坑2333 等我把代码写完了再写
- chrome 浏览器如何安装草料二维码
https://cli.im/news/6527 实测有效
- 题解 P2598 【[ZJOI2009]狼和羊的故事】
P2598 [ZJOI2009]狼和羊的故事 题目描述 "狼爱上羊啊爱的疯狂,谁让他们真爱了一场:狼爱上羊啊并不荒唐,他们说有爱就有方向......" Orez听到这首歌,心想:狼 ...
- C语言 两个小知识点
strlen 函数原型 extern unsigned int strlen(char *s); 在Visual C++ 6.0中,原型为size_t strlen(const char *strin ...