1280:【例9.24】滑雪

2023-12-21 07:20
文章标签 滑雪 9.24 1280

本文主要是介绍1280:【例9.24】滑雪,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

【解题思路】
1. 状态定义
状态定义:dp[i][j]:从(i,j)出发的所有路线中,长度最长的路线的长度。

2. 状态转移方程
记第(i,j)位置的高度为a[i][j]
集合:从(i,j)出发的所有路线
分割集合:根据下一步可以到达的位置分割集合。
下一步可以到达的位置有:(i-1,j), (i+1,j), (i,j-1), (i,j+1)。只要该位置的高度低于当前(i,j)位置的高度,就可以到达这里。

如果a[i-1][j] < a[i][j],那么下一步可以到(i-1,j)。从(i,j)出发的最长路线长度,为从(i-1,j)出发的最长路线长度再加1,即dp[i][j] = dp[i-1][j] + 1
如果a[i+1][j] < a[i][j],那么下一步可以到(i+1,j)。从(i,j)出发的最长路线长度,为从(i+1,j)出发的最长路线长度再加1,即dp[i][j] = dp[i+1][j] + 1
如果a[i][j-1] < a[i][j],那么下一步可以到(i,j-1)。从(i,j)出发的最长路线长度,为从(i,j-1)出发的最长路线长度再加1,即dp[i][j] = dp[i][j-1] + 1
如果a[i][j+1] < a[i][j],那么下一步可以到(i,j+1)。从(i,j)出发的最长路线长度,为从(i,j+1)出发的最长路线长度再加1,即dp[i][j] = dp[i][j+1] + 1
以上四种情况求最大值。
由于在求(i,j)时,其上下左右四个位置的状态:dp[i-1][j], dp[i+1][j], dp[i][j-1], dp[i][j+1]并不能确定都已经求出来了。因此可以通过记忆化递归的方法来求解状态。
设函数dfs(i, j),作用为求解状态dp[i][j]。如果dp[i][j]已经求出来了(值大于0),那么直接返回dp[i][j]。否则通过上述状态转移方程递归求解。

遍历所有的位置,求出从每个位置出发的路线的最长长度,求它们中的最大值,即为该问题的结果。

【题解代码】

#include <iostream>using namespace std;const int N = 105;int n, m, a[N][N], dp[N][N];
int mov[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};bool ok(int x, int y) {return x > 0 && x <= n && y > 0 && y <= m;
}int dfs(int x, int y) { //返回从起点开始最多能滑几步(不包含起点)if (dp[x][y] != 0)return dp[x][y];int maxn = 0;for (int i = 0; i < 4; i ++) {int dx = x + mov[i][0];int dy = y + mov[i][1];if (ok(dx, dy) && a[dx][dy] < a[x][y]) {maxn = max(maxn, dfs(dx, dy));}}return dp[x][y] = maxn + 1;
}int main() {scanf ("%d %d", &n, &m);for (int i = 1; i <= n; i ++)for (int j = 1; j <= m; j ++)scanf ("%d", &a[i][j]);int ans = 0;for (int i = 1; i <= n; i ++)for (int j = 1; j <= m; j ++)ans = max(ans, dfs(i, j));printf ("%d", ans);return 0;
}


 

这篇关于1280:【例9.24】滑雪的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/519084

相关文章

滑雪 POJ 1088

回溯 + DFS #include<cstdio>#include<cstring>#include<iostream>using namespace std;#define MAXD 100 + 10int R,C;int G[MAXD][MAXD];int d[MAXD][MAXD] = {0}; /*到达 i j 时候的最大长度*/int max_size = 0;#

一不小心给桌面粘贴了1280个文件怎么办?

搞了一下午很混乱,慌乱中不小心将一个文件夹里的1280个包粘贴在了桌面上,         完后都没有撤销粘贴这个鼠标右键功能,反而还可以再粘贴。         很懵逼,只能把桌面上可以看见的多余文件删除,那么看不见的呢又拽不出来。         同时发现刷新桌面会很有明显的卡顿,说明那些文件确实还存在着,比之前的响应速度慢多了。         苦逼中去百度了一下然而

杭电1280 前m大的数(哈希表)

前m大的数 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 9557    Accepted Submission(s): 3350 Problem Description 还记得Gardon给小希布置的那个作业么?(上次比赛的1

1280短信套餐

题目描述 某通信公司为推广手机短信,提出了短信套餐优惠政策。 用户必须选择一种短信套餐,且只能选择一种。每种套餐的形式为:每月交p元,可以发送免费短信f条。如果超过了f条,则超过的部分按每条a元收费。 现在你已经预知下个月需要发送m条短信。这家公司的短信套餐种类太多了,请你编个程序告诉他选择最省钱的短信套餐需要交多少钱? 输入 输入有多组数据。每组数据第一行为整数n和m,用一个空

搜索学习(1)--POJ 1088滑雪 NYOJ 10

题目链接:   poj:click here.   NYOJ :click here 搜索的经典,记忆化搜索,可以用dp实现, 思路:做了一天了,关键在于记录路径的二维数组和存储图的数组,当前点四个方向都搜一遍,搜了一遍记录被访问了,高度下降才是符合要求,同时最长路径在搜的同时及时更新, 调了好几遍,搜索题目还是发现没能把图抽象化语言去实现,以后要加强,不过发现nyoj能过,同样的代码交到

Algorithm学习笔记 --- 滑雪

滑雪 Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 72367 Accepted: 26712 Description Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个区域中最长底

POJ-1088 滑雪 记忆化搜索

题目链接 #include <stdio.h>#include <string.h>#include <iostream>#include<functional>#include <queue>#include <string>#include <algorithm>using namespace std;const int maxn = 105;int n,m;i

【DFS】poj 1088 滑雪

滑雪 Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 76064 Accepted: 28203 Description Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个区域中最长

滑雪--记忆化搜索

Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个区域中最长底滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子 1 2 3 4 516 17 18 19 615 24 25 20 714 23 22 21 813 12 11 10

poj——1280——前m大的数

Problem Description 还记得Gardon给小希布置的那个作业么?(上次比赛的1005)其实小希已经找回了原来的那张数表,现在她想确认一下她的答案是否正确,但是整个的答案是很庞大的表,小希只想让你把答案中最大的M个数告诉她就可以了。  给定一个包含N(N<=3000)个正整数的序列,每个数不超过5000,对它们两两相加得到的N*(N-1)/2个和,求出其中前M大的数(M<=1000