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

题干:

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到底地面时可能的最早时间。

 

AC代码1:

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
const int INF = 0x3f3f3f3f;
int n,x,y,maxx;
int dp[1005][2];//fg=0代表左边,fg=1代表右边 
struct Node {int l,r,h;
} node[1005];
bool cmp(const Node & a,const Node & b) {return a.h < b.h;
}
int dfs(int cur,int fg) {if(cur == 1) return 0;if(dp[cur][fg] != -1) return dp[cur][fg];if(cur == 1) {return 0;}int ans = INF;if(dp[cur][fg] != -1) {return dp[cur][fg];}int temp = cur;	for(int i = cur-1; i>=1; i--) {temp=i;if(node[cur].h - node[i].h > maxx) break;if(fg==0) {if(node[i].l <= node[cur].l && node[i].r >= node[cur].l) {ans = min(dfs(i,0)+node[cur].l-node[i].l,dfs(i,1) +node[i].r-node[cur].l );break;}} else {if(node[i].r >= node[cur].r && node[i].l <= node[cur].r) {ans = min(dfs(i,0)+node[cur].r-node[i].l,dfs(i,1)+node[i].r-node[cur].r);break;}}}if(ans == INF) {if(node[cur].h <= maxx) return dp[cur][fg] = 0;else return dp[cur][fg] = ans;}else return dp[cur][fg] = ans;
}
int main()
{int t;cin>>t;while(t--) {scanf("%d%d%d%d",&n,&x,&y,&maxx);memset(dp,-1,sizeof (dp));for(int i = 1; i<=n; i++) {scanf("%d%d%d",&node[i].l,&node[i].r,&node[i].h);}sort(node+1,node+n+1,cmp);int ok=n+1;
//		node[ok].h = y;node[ok].l=node[ok].r=x;for(int i = n; i>=1; i--) {if(node[i].r >= x && node[i].l <= x) {ok=i;break;}}if(ok == n+1) {printf("%d\n",y);}else {int ans = min(dfs(ok,1) + node[ok].r-x,dfs(ok,0) + x-node[ok].l) + y;
//			int ans = min(dfs(ok,1),dfs(ok,0)) + y;printf("%d\n",ans);}}	return 0 ;} 
//1
//1
//2 3
//100
//5 6 1

AC代码2:

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
const int INF = 0x3f3f3f3f;
int n,x,y,maxx;
int dp[1005][2];//fg=0代表左边,fg=1代表右边 
struct Node {int l,r,h;
} node[1005];
bool cmp(const Node & a,const Node & b) {return a.h < b.h;
}
int dfs(int cur,int fg) {if(cur == 1) return 0;if(dp[cur][fg] != -1) return dp[cur][fg];
//	int minn = 0x3f3f3f3f,flag=0;//0左  1右 
//	int temp=cur;int ans = INF;int temp = cur;	for(int i = cur-1; i>=1; i--) {temp=i;if(node[cur].h - node[i].h > maxx) break;if(fg==0) {if(node[i].l <= node[cur].l && node[i].r >= node[cur].l) {ans = min(dfs(i,0)+node[cur].l-node[i].l,dfs(i,1) +node[i].r-node[cur].l );break;}} else {if(node[i].r >= node[cur].r && node[i].l <= node[cur].r) {ans = min(dfs(i,0)+node[cur].r-node[i].l,dfs(i,1)+node[i].r-node[cur].r);break;}}}if(ans == INF) {if(node[cur].h <= maxx) return dp[cur][fg] = 0;else return dp[cur][fg] = ans;}else return dp[cur][fg] = ans;
//	if(ans == INF) {
//		if(temp == 1) {
//			if(node[cur].h > maxx) return dp[cur][fg] = ans; 
//			else return dp[cur][fg] = 0;
//		}
//		return dp[cur][fg] = ans;
//	} 
//	else return dp[cur][fg] = ans;
}
int main()
{int t;cin>>t;while(t--) {scanf("%d%d%d%d",&n,&x,&y,&maxx);memset(dp,-1,sizeof (dp));for(int i = 1; i<=n; i++) {scanf("%d%d%d",&node[i].l,&node[i].r,&node[i].h);}sort(node+1,node+n+1,cmp);int ok=n+1;node[ok].h = y;node[ok].l=node[ok].r=x;
//		for(int i = n; i>=1; i--) {
//			if(node[i].r >= x && node[i].l <= x) {
//				ok=i;break;
//			}
//		}
//		int ans = min(dfs(ok,1) + node[ok].r-x,dfs(ok,0) + x-node[ok].l) + y;int ans = min(dfs(ok,1),dfs(ok,0)) + y;printf("%d\n",ans);}	return 0 ;} 

错误代码:

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
int n,x,y,maxx;
int dp[1005];
struct Node {int l,r,h;
} node[1005];
bool cmp(const Node & a,const Node & b) {return a.h < b.h;
}
int dfs(int cur,int curx,int curh) {if(curh == 0) return 0;if(cur < 0) return 0;if(dp[cur] != -1) return dp[cur];int minn = 0x3f3f3f3f;for(int i = cur-1; i>=1; i--) {if(curh - node[i].h > maxx) break;if(node[i].l <= node[cur].l) minn = min(minn,dfs(i,node[cur].l,node[i].h)+node[cur].l-curx);if(node[i].r >= node[cur].r) minn = min(minn,dfs(i,node[cur].r,node[i].h)+node[cur].r-curx);}return dp[cur] = minn;
}
int main()
{int t;cin>>t;while(t--) {scanf("%d%d%d%d",&n,&x,&y,&maxx);memset(dp,-1,sizeof (dp));for(int i = 1; i<=n; i++) {scanf("%d%d%d",&node[i].l,&node[i].r,&node[i].h);}sort(node+1,node+n+1,cmp);printf("%d\n",dfs(n,x,node[n].h));}	
//	18653293769return 0 ;} 

总结:

   几个地方是真的坑,首先这个错误代码,记忆化搜素的设计状态我就没搞明白(因为后来我通过观察发现一维dp表示不了所有状态),于是dfs中乱设了一堆参数,结果显然都没用。

   其二,函数内部,显然要break,不能不加break,因为有上一个台子挡住了,后面即使有符合的,也不能跳上去了,所以要break。

   其三,要处理好到地面的那一步,一定是直接跳过去的(也就是 一定ans==INF),所以return的时候不能直接retrun dp[cur][fg] = ans;而应该判断是否ans==INF 如果等于的话,也就说明是到地面了,要dp[cur][fg] = 0;才可以。

   其四,有个处理技巧,让出发点当成一个新的平台,这样直接统一形式就可以了。不然的话,就跟AC代码1一样,先判断是否从出发点可以直接落到地面上,特判一下这个条件才可以。

  其五,有个技巧,就是高度都最后统一算,直接+y就可以了,这样减少了代码出错概率。

  其六,递归函数中的状态转移要想清楚,到底是由哪些状态转移而来,或者想,可以转移到哪些状态去。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/441622.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c语言linux消息机制,linux消息机制的过程是什么啊,请赐教

LINUX的安装过程很简单,按照它的提示进行就可以了.重点就是分区那里.通常我们使用双系统,那样我们在LINUX分区的时候不要把WIN分区跟格掉就好,然后要记得分一个SWAP分区,然后根据您的需要进行相应的分区,比如/HOME,/USR,/VAR等等.下面介绍一下具体操作步骤&#xff1a;假定用户…

ACM与Java -- 大整数类的常用函数一览表

BigInteger abs() 此方法返回一个BigInteger&#xff0c;其值是此BigInteger的绝对值。2BigInteger add(BigInteger val) 此方法返回一个BigInteger&#xff0c;其值是(this val).3BigInteger and(BigInteger val) 此方法返回一个BigInteger&#xff0c;其值是 (this & v…

linux虚拟机上安装域名,虚拟机如何安装linux系统

虚拟机如何安装linux系统&#xff1f;安装linux系统首先要在电脑上安装好虚拟机&#xff0c;然后逐步进行linux系统安装。大致介绍下安装的流程。1.首先打开虚拟机软件,点击文件/新建虚拟机&#xff0c;用户可以按照默认选择&#xff0c;然后点击下一步。2.在浏览里&#xff0c…

想打ACM?想刷题?来这些online judge!

原文地址&#xff1a;https://blog.csdn.net/tigerisland45/article/details/52134189

基于arm下的Linux控制,基于ARMuCLinux的网络控制系统设计与实现

引言 随着网络和通信技术的发展&#xff0c;嵌入式系统现已进入高速发展阶段。并在社会各个领域得到了广泛的应用。本文介绍了一种采用ARMuCLinux作为开发平台。实现基于TCP&#xff0f;IP的远程系统监控&#xff0e;从而取代传统单片机来实现数据采集、预处理和通信功能&am…

【qduoj - 1121】小明的贪心题(Dijkstra最短路 + 最短路条数)

题干&#xff1a; 小明的贪心题 描述 小明来到青岛上学已经一年了&#xff0c;他给青岛这座城市画了一张地图。在这个地图上有n个点&#xff0c;小明的起始点为1号点&#xff0c;终点为n号点&#xff0c;并且地图上的所有边都是单向的。小明知道从i号点到j号点的时间花费为w分…

nodejs 监控linux,linuxServerMonitoring

linux服务器监控平台技术&#xff1a;nodejs vue java mongodb springboot linux shelllinux服务器监控项目&#xff0c;前后端分离vuespringbootmongodb&#xff1a;1、启动前台&#xff1a;使用命令&#xff1a;A 先安装nodejs并配置好环境变量B 先控制台cmd命令切换到项目目…

【qduoj - 纳新题】小明的dp(快速幂 + 乘法原理)(简单组合数学)

题干&#xff1a; 描述 小明有n种珠宝&#xff0c;每种无限个&#xff0c;他想从这些珠宝中取出m个&#xff0c;编成手链&#xff08;长链哦&#xff09;&#xff0c;并按顺序排列起来&#xff0c;为了好看&#xff0c;相邻的珠宝不能相同。小明想知道有多少种排列的方法。 输…

linux查看显卡核心数,linux查看硬件信息,linux查看硬盘信息,linux查看CPU信息,linux查看显卡,硬件型号信息 | 帮助信息-动天数据...

linux查看硬件信息,linux查看硬盘信息,linux查看CPU信息,linux查看显卡,硬件型号信息作者&#xff1a;dthost |时间&#xff1a;2015-09-30 |8,325 次阅读linux服务器大家都知道&#xff0c;他和WIN系统不一样&#xff0c;他不能和WIN电脑一样&#xff0c;用桌面的电脑属性查看…

【qduoj - 纳新题】凑数题(恰好装满类0-1背包 或 母函数)

题干&#xff1a; 描述 小Q手里有n枚硬币&#xff0c;每枚硬币有一定的金额x,他想知道&#xff0c;用这些硬币能组成多少种不同的金额。但是他太笨了&#xff0c;自己数懵了&#xff0c;你来帮帮他好不好&#xff1f; 注意&#xff1a;组成金额时&#xff0c;每枚硬币只能用一…

c语言中short作用,C语言short

C语言short教程C语言short定义详解语法short int varname value;short varname1 value2; //简写形式参数参数描述short int定义 short 类型变量使用的类型。varname变量名。value可选&#xff0c;变量的初始值&#xff0c;该值不可以超过 short 类型的最大值。说明使用 short…

dls的BM算法模板(线性递推问题,解决矩阵快速幂解决不了的问题)

模板&#xff1a;往里面扔数就可以了&#xff08;据说>8个&#xff1f;&#xff09;%%%dls https://www.cnblogs.com/zzqsblog/p/6877339.html #include<bits/stdc.h> using namespace std; #define rep(i,a,n) for (int ia;i<n;i) #define per(i,a,n) for (int …

c语言课题设计字符串处理函数报告,C语言输入输出库函数设计实验报告.doc

C语言输入输出库函数设计实验报告第 PAGE \* MERGEFORMAT I页 共 SECTIONPAGES \* MERGEFORMAT 1页华中科技大学计算机科学与技术学院C语言课程设计报告题目: C输入输出库函数的程序设计专 业&#xff1a; 计算机科学与技术班 级&#xff1a; CS1202学 号&#xff1a; U2012148…

【HDU - 1847】Good Luck in CET-4 Everybody! (巴什博奕,PN图或sg函数)

题干&#xff1a; 大学英语四级考试就要来临了&#xff0c;你是不是在紧张的复习&#xff1f;也许紧张得连短学期的ACM都没工夫练习了&#xff0c;反正我知道的Kiki和Cici都是如此。当然&#xff0c;作为在考场浸润了十几载的当代大学生&#xff0c;Kiki和Cici更懂得考前的放松…

词法分析器c语言带注释,C语言词法分析器内容说明注释完整可运行代码.doc-资源下载在线文库www.lddoc.cn...

C语言词法分析器_内容说明注释完整_可运行代码.doc1. 实验目的及要求 本次实验通过用 C 语言 设计、编制、调试一个词法分析子程序&#xff0c;识别单词&#xff0c;实现一个 C 语言词法分析器&#xff0c;经过此过程可以加深对编译器解析单词流的过程的了解。 运行环境运行环境…

【HDU - 2516 】取石子游戏 (Fibonacci博弈)

题干&#xff1a; 1堆石子有n个,两人轮流取.先取者第1次可以取任意多个&#xff0c;但不能全部取完.以后每次取的石子数不能超过上次取子数的2倍。取完者胜.先取者负输出"Second win".先取者胜输出"First win". Input 输入有多组.每组第1行是2<n<…

打印心形c语言,C语言打印心形

#include int main() {for (float y 1.5f; y > -1.5f; y - 0.1f) {for (float x -1.5f; x < 1.5f; x 0.05f) {float a x * x y * y - 1;putchar(a * a * a - x * x * y * y * y < 0.0f ? ‘*‘ : ‘ ‘);}putchar(‘\n‘);}}**********************************…

【HDU - 1564 】Play a game (博弈问题,找规律,奇偶博弈)

题干&#xff1a; New Year is Coming! ailyanlu is very happy today! and he is playing a chessboard game with 8600. The size of the chessboard is n*n. A stone is placed in a corner square. They play alternatively with 8600 having the first move. Each time…

c语言学生对老师的评教系统,学生对老师的评价

学生对老师的评价1、老师授课的方式十分适合我们&#xff0c;他根据本课程知识结构的特点&#xff0c;重点突出&#xff0c;层次分明。理论和实际相结合&#xff0c;透过例题使知识更条理化。但授课速度有点快&#xff0c;来不及记录。2、老师在生活工作中给人的感觉是生活朴素…

*【HDU - 1517】【POJ - 2505】A Multiplication Game(博弈,递推找规律或SG函数)

题干&#xff1a; Stan and Ollie play the game of multiplication by multiplying an integer p by one of the numbers 2 to 9. Stan always starts with p 1, does his multiplication, then Ollie multiplies the number, then Stan and so on. Before a game starts, t…