题目
题解思路
解题很简单🍳,使用动态规划是就好了 ✔
状态:dp[i][j]从i,j位置出发所能滑的最大长度。
状态转移方程:dp[i][j]=max(dp[i-1][j],dp[i][j-1],dp[i][j+1],dp[i+1][j])+1 ✔
简单的动态规划的题不会很难,而这种很明显就是增加了一些额外条件的动态规划。状态不变,状态转移方程也不变,只是计算状态转移方程是多了一个条件,因为只能往低的地方滑所以只有arr[i-1][j]<a[i][j]才能考虑转移向dp[i-1][j](即只有满足这个条件才能在max中比较,max中每一个状态都是,所以不妨先判断一下如果不满足则将值设置为0参与比较也没事)✔
注意边界条件,当i>0或者i>=R时直接返回0而j(i为行j为列)也要和0和C比较。并且要注意的是,在状态转移时涉及dp[i-1][j]等状态,分别也要保证行和列在有效范围内! ✔
题解(AC+注释)
打开🌏 开始🏂
#include<iostream>
#include<algorithm>//有很多算法函数,至少可以用min哦
#include<cstring>//使用memsent需要
using namespace std;
int a[110][110] = {}; //因为slove递归函数需要,程序也不复杂不妨设置为全局变量
int dp[110][110] = {};//同上
int R, C; //上
int slove(int i, int j)//返回从i j位置出发的最长滑雪长度
{
if (i < 0 || i >= R || j < 0 || j >= C)return 0;//如果超出边界返回0哦(因为此处不可滑)
if (dp[i][j] != 0)return dp[i][j]; //如果计算过直接返回(空间换时间可别少了)
int q = -1, w = -1, e = -1, r = -1;//初始化四条路最长滑雪长度为-1,如果计算过还为-1则可知此路不通
if (i - 1 < 0)q = 0;//如果超出边界则为0
else if (a[i - 1][j] < a[i][j])//如果更低
q = slove(i - 1, j);//如果既没有超出边界又较低才可算上
if (j - 1 < 0)w = 0;//同上
else if (a[i][j - 1] < a[i][j])
w = slove(i, j - 1);
if (j + 1 >= C)e = 0;//同上
else if (a[i][j + 1] < a[i][j])
e = slove(i, j + 1);
if (i + 1 >= R)r = 0;//同上
else if (a[i + 1][j] < a[i][j])
r = slove(i + 1, j);
if ((q + w + e + r) == -4)return dp[i][j] = 1;//如果都不通返回1!因为滑雪滑的是滑块,滑自己这块长度为1
return dp[i][j] = 1 + max(max(q, w), max(e, r));//如果至少有一条通路则状态转移(较高的会被设置为0,比较也没事)
}
int main()
{
cin >> R >> C;
for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
cin >> a[i][j];//输入地图
}
}
memset(dp, 0, sizeof(dp));//将所有值设为0,0仅表示未计算
int max = 0;
for (int i = 0; i < R; i++)//要求从每一个位置出发的值
{
for (int j = 0; j < C; j++)
{
int x = slove(i, j);
if (x > max)max = x;//记录最大值
}
}
cout << max << endl;//输出最大值结果
return 0;
}