滑雪——记忆化搜索

滑雪

https://ac.nowcoder.com/acm/problem/105685

滑雪

题意:

在二维数组中找到一条数字逐渐减小的最长的路径,输出路径长度

思路:

确定状态:

dp[i] [j] 表示从(i,j)开始走的最长路径的长度

原问题:

从(1,1)到(n,m)任意一点开始走的最长路径的长度

状态转移方程:

dp[i] [j] = max{dp[i - 1] [j] + 1, dp[i + 1] [j] + 1, dp[i] [j - 1], dp[i] [j + 1]}

显然for循环没法一次性解决,之前的题都是按一定顺序,如从1到n,而现在你有四个方向,循环跑i,j的时候,你需要知道[i - 1] [j], [i + 1] [j],[i] [j + 1], [i] [j - 1]的值,可你不一定有他们的值,所以没法跑之前的dp,那我们就使用秘技:记忆化搜索

搜这个i,j的点的时候,判断一下这个点有没有值,如果有值就直接返回该值,如果没有,就去算他周围的四个点的,求最大值,并返回,注意判断是否出界

#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <stdlib.h>
#include <sstream>
#include <map>
#include <set>
using  namespace std;
#define inf 0x3f3f3f3f
#define MAX 1000000 + 7
#define endl '\n'
#define mod 1e9+7;
typedef  long long ll ;
//不开longlong见祖宗!
//ios::sync_with_stdio(false);
//cin.tie(0); cout.tie(0);
inline int IntRead(){char ch = getchar();int s = 0, w = 1;while(ch < '0' || ch > '9'){if(ch == '-') w = -1;
        ch = getchar();}while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0';ch = getchar();}return s * w;}

int n, m, ans;
int tr[105][105], dp[105][105];

bool judge(int x, int y){
    if(x < 1 || x > n || y < 1 || y > m)return false;
    return true;
}

int calc(int i, int j){
    if(dp[i][j] != 0)return dp[i][j];
    dp[i][j] = 1;
    if(tr[i - 1][j] < tr[i][j] && judge(i - 1, j))dp[i][j] = max(dp[i][j], calc(i - 1, j) + 1);
    if(tr[i + 1][j] < tr[i][j] && judge(i + 1, j))dp[i][j] = max(dp[i][j], calc(i + 1, j) + 1);
    if(tr[i][j - 1] < tr[i][j] && judge(i, j - 1))dp[i][j] = max(dp[i][j], calc(i, j - 1) + 1);
    if(tr[i][j + 1] < tr[i][j] && judge(i, j + 1))dp[i][j] = max(dp[i][j], calc(i, j + 1) + 1);
    return dp[i][j];
}

int main(){
    cin>>n>>m;
    for(int i = 1; i <= n; ++i)
    for(int j = 1; j <= m; ++j){
        tr[i][j] = IntRead();
    }
    for(int i = 1; i <= n; ++i)
    for(int j = 1; j <= m; ++j){
        calc(i, j);
    }
    ans = -1e9;
    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;
}
全部评论

相关推荐

点赞 评论 收藏
分享
01-23 14:54
同济大学 Java
热爱敲代码的程序媛:给你提几点【专业技能】这个模块里面可优化的地方:1.【具备JVM调优经验】可以去b站上搜一下JVM调优的视频,估计一两个小时凭你的学习能力就能掌握JVM调优的实践方面的技能。2.【MySql优化】MySql这一栏,你去b站或者找个博客看看MySql优化,学一下,如果你本身比较熟悉MySql语句的话,那基本半天时间凭你的学习能力MySql语句优化方面的技能你也能掌握个差不多。以上1,2两点主要是因为我看你专业技能大部分都说的是偏理论,没有写应用。再就是最后,你结合你的项目,想一想你的项目中哪些sql语句是可以用MySql优化的,到时候你面试的时候也好结合着说一下。
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务