实际上规划问题可以用递归求解
滑雪
只能走比当前低的格子,求最多走多少格
状态表示
f[i][j]
存以第 i 行第 j 个为起点的所有可能路径
属性是 MAX
状态计算
分类:
- 向右
- 向左
- 向上
- 向下 这样可以分为不重不漏的四类
在能走的路径中,(以向下走为例)f[i][j] = f[i+1][j] + 1
遍历所有点,因为有限定条件(往低处走),所以不会有回路,相互依赖导致不能求解
记住每点最小值为 1
实现
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 330;
int h[N][N];
int f[N][N];
//偏移量
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
int n, m;
int dp(int i, int j)
{
//引用 V = f[i][j]
int &V = f[i][j];
if(V != -1) //走过
return V;
//最少是自己一格
V = 1;
for(int k = 0; k < 4; k ++)
{
int a = i + dx[k], b = j + dy[k];
if(a >= 1 && a <= n && b >= 1 && b <= m && h[i][j] > h[a][b])
V = max(V, dp(a, b) + 1);
}
return V;
}
int main()
{
cin >> n >> m;
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= m; j ++)
cin >> h[i][j];
//赋初值,用于判断当前值有没有走过
memset(f, -1, sizeof f);
int ans = 0;
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= m; j ++)
ans = max(ans, dp(i, j));
cout << ans << endl;
return 0;
}