POJ1088 滑雪(动态规划+深搜DFS)
来源:互联网 发布:过期未注册域名查询 编辑:程序博客网 时间:2024/04/30 16:23
题目:
滑雪
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 94177 Accepted: 35668
Description
Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个区域中最长底滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子
一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-...-3-2-1更长。事实上,这是最长的一条。
1 2 3 4 516 17 18 19 615 24 25 20 714 23 22 21 813 12 11 10 9
一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-...-3-2-1更长。事实上,这是最长的一条。
Input
输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。
Output
输出最长区域的长度。
Sample Input
5 51 2 3 4 516 17 18 19 615 24 25 20 714 23 22 21 813 12 11 10 9
Sample Output
25
Source
SHTSC 2002
[Submit] [Go Back] [Status] [Discuss]
思路:一开始用搜索写的,不管怎么剪枝都超时不AC。。没办法了,就用dp的方法,保存每一步所能达到的最大状态
代码1(搜索,POJ未AC(超时),在NYOJ上可以AC):
#include <stdio.h>#include <string.h>#include <iostream>#include <stack>#include <queue>#include <vector>#include <cmath>#include <algorithm>#define mem(a,b) memset(a,b,sizeof(a))using namespace std;int map[110][110];int go[4][2]= {{1,0},{-1,0},{0,1},{0,-1}};//四个方向int ans;int r,c,step,num;struct node{ int x; int y; int sum;} a[20000];//让搜索的顺序从最大的山依次往下搜索,然而还是超时bool cmp(node x,node y){ return x.sum>y.sum;}void dfs(int x,int y){ if(map[x][y]+step<ans)return; if(map[x][y]<map[x+1][y]&&map[x][y]<map[x-1][y]&&map[x][y]<map[x][y+1]&&map[x][y]<map[x][y-1])//如果四面都是高山就代表不能搜了 { ans=max(step,ans); return; } for(int i=0; i<4; i++) { int xx=x+go[i][0]; int yy=y+go[i][1]; if(xx>0&&xx<=r&&yy>0&&yy<=c&&map[xx][yy]<map[x][y])//判断越界 { step++; dfs(xx,yy); step--;//避免回头路 } }}int main(){ while(~scanf("%d%d",&r,&c)) { ans=0; num=0; for(int i=0; i<=r+1; i++) { map[i][0]=99999; map[i][c+1]=99999; } for(int i=0; i<=c; i++) { map[0][i]=99999; map[r+1][i]=99999; }//给外圈加一圈99999 for(int i=1; i<=r; i++) for(int j=1; j<=c; j++) { scanf("%d",&map[i][j]); a[num].x=i; a[num].y=j; a[num].sum=map[i][j]; num++; } sort(a,a+num,cmp); for(int i=0; i<num; i++) { step=1; dfs(a[i].x,a[i].y); }//依次深搜 printf("%d\n",ans); } return 0;}
代码2(dp+深搜,AC):
#include <stdio.h>#include <string.h>#include <iostream>#include <stack>#include <queue>#include <vector>#include <cmath>#include <algorithm>#define mem(a,b) memset(a,b,sizeof(a))using namespace std;int map[110][110];int dp[110][110];int r,c;int go[4][2]= {{1,0},{0,1},{-1,0},{0,-1}};int dfs(int x,int y){ if(dp[x][y]) return dp[x][y];//dp[x][y]在坐标以(x,y)为顶点,所能达到的最长区域的长度 for(int i=0; i<4; i++) { int xx=x+go[i][0]; int yy=y+go[i][1]; if(map[xx][yy]<map[x][y]&&xx>=1&&xx<=r&&yy>=1&&yy<=c)//下一步必须必这一步小,且不能越界 dp[x][y]=max(dp[x][y],dfs(xx,yy));//更新每一步的dp值 } dp[x][y]++;//当前状态的步数加一 return dp[x][y];}int main(){ while(~scanf("%d%d",&r,&c)) { mem(dp,0); int maxx=0; for(int i=1; i<=r; i++) for(int j=1; j<=c; j++) scanf("%d",&map[i][j]); for(int i=1; i<=r; i++) for(int j=1; j<=c; j++) maxx=max(maxx,dfs(i,j));//更新最大值 printf("%d\n",maxx); }}优化时间很重要~
0 0
- POJ1088 滑雪(动态规划+深搜DFS)
- POJ1088 滑雪【动态规划】
- poj1088 滑雪 动态规划+回溯
- 【动态规划】 POJ1088 滑雪问题
- poj1088滑雪,记忆搜索,动态规划问题
- poj1088滑雪搜索dfs
- poj1088 滑雪(dfs)
- poj1088 滑雪 DP+DFS
- 滑雪(动态规划+dfs)
- POJ1088 滑雪 && NYOJ 10 skiing 经典的动态规划练习题
- 动态规划-poj1088 滑雪 ---增加了最优路径构建
- POJ1088滑雪问题 简单dp(动态规划)已AC
- poj1088 滑雪(dfs、dp优化)
- poj1088滑雪(dfs+记忆化搜索、备忘录)
- poj1088滑雪【dfs or 记忆化搜索】
- DFS:POJ1088-滑雪(记忆化搜索)
- poj1088滑雪(记忆化dfs)
- poj1088(动态规划经典)
- 居中相对定位和绝对定位的元素
- iso小练习,获取界面的空间,变量字符串int循环判断,get请求数据
- leetcode刷题之旅——215. Kth Largest Element in an Array
- C#加密整理
- Lua 数据结构
- POJ1088 滑雪(动态规划+深搜DFS)
- android的Space控件使用方式
- lavarel框架学习之使用ajax提交表单方法详解
- JSPatch详解
- 滑动改变toolbar透明度
- Creating Custom Views
- redis 主从复制配置
- 最新win10镜像下载
- 使用WinSCP软件在windows和ubuntu中进行文件传输