题目描述 Description
trs喜欢滑雪。他来到了一个滑雪场,这个滑雪场是一个矩形,为了简便,我们用r行c列的矩阵来表示每块地形。为了得到更快的速度,滑行的路线必须向下倾斜。
例如样例中的那个矩形,可以从某个点滑向上下左右四个相邻的点之一。例如24-17-16-1,其实25-24-23…3-2-1更长,事实上这是最长的一条。
输入描述 Input Description
输入文件
第1行: 两个数字r,c(1<=r,c<=100),表示矩阵的行列。
第2..r+1行:每行c个数,表示这个矩阵。
输出描述 Output Description
输出文件
仅一行: 输出1个整数,表示可以滑行的最大长度。
样例输入 Sample Input
5 5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
样例输出 Sample Output
25
第一次打了个手打队列的宽搜,居然A了四个点嘿嘿嘿嘿嘿
orz57级wzd和wyh两个DP大佬
第一道记忆化搜索的题目。
思路是以每一个点为起点进行dfs,用dp数组记录下每次搜到的最长路
一开始傻傻的认为不同起点时搜到的每个点的最长路是不一样的QAAAQ
嘛,递归就是相同的过程一层层算下去
既然一开始要求最优解的话,那程序得到的每一层结果也一定是最优的
也可以理解成滑到那里忽然翻车了滑到的最长路径是多少23333
这样,当搜到一个节点,发现已经搜到过他的最长路,那就直接调用
已经知道翻车前最多滑多远了,爬起来继续滑还能滑多远呢23333
#include<iostream>
#include<cstdio>
using namespace std;
const int MAXN = 1000 + 1;
int map[MAXN][MAXN],dp[MAXN][MAXN],maxx;
int mu[] = {0,-1,1,0},
mr[] = {1,0,0,-1};
int dfs(int k,int j)
{
if(dp[k][j]) return dp[k][j];
int ans = 1;
for(int i = 0; i < 4; i ++)
{
int x = k + mu[i] ;
int y = j + mr[i] ;
if(map[x][y] > map[k][j])
ans = max(ans, dfs(x, y) + 1);
}
return dp[k][j] = ans;
}
int m,n;
int main()
{
cin >> m >> n;
for(int i = 1; i <= m; i ++)
for(int j = 1; j <= n;j ++)
cin >> map[i][j];
for(int i = 1; i <= m; i ++)
for(int j = 1; j <= n;j ++)
{
dp[i][j] = max(dfs(i,j),dp[i][j]);
maxx = max(maxx, dp[i][j]);
}
cout << maxx;
return 0;
}