POJ1088滑雪/Hrbust1179下山 (DFS+记忆化搜索)

刚学习了记忆化搜索,写了这篇博客记录一下。
先附上题目链接(这两道题是一道题)
POJ1088滑雪:

http://poj.org/problem?id=1088

Hrbust1179下山:

http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1179

不知道从哪儿进入dfs,直接暴搜的话TLE,所以需要开一个数组记录每个点的最长路径,进行记忆化搜索,这样每搜索一个点时,如果这个点被搜索过,那么就可以直接拿结果来用,从而降低了时间复杂度。

更为详细的说明写在了注释。

代码如下:(以下为POJ的AC代码,Hrbust1179题还需要加上多组输入)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <iterator>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define ms(s, x) memset(s,x,sizeof(s))
#define pb push_back
#define inf 0x3f3f3f3f
typedef long long ll;
using namespace std;

const int MAXN = 1e5+5;
const int MOD = 1e9+7;

int r, c;
int pic[105][105];
int rec[105][105]; //记录每个点所能达到的最长路径
char dir[4][2] = {-1,0, 0,-1, 1,0, 0,1};//左上右下四个方向

int dfs(int x0, int y0)
{
    if (rec[x0][y0] != -1)
        return rec[x0][y0];//如果这个点已经被搜索过,那么直接拿其结果来用
    rec[x0][y0] = 1;//如果没有搜索过,将值改为1,表示自身这一点
    rep(i, 0, 3) 
    {
        int x = x0 + dir[i][0];
        int y = y0 + dir[i][1];
        if (x>0 && y>0 && x<=r && y<=c && pic[x][y] < pic[x0][y0])
            rec[x0][y0] = max(rec[x0][y0], dfs(x, y)+1);
            //找出这一点向四个方向所能达到的最长路径,并记录下来
            //因为能够到达下一个点,所以是dfs(x,y)+1
    }
    return rec[x0][y0]; //返回这一点的搜索结果
}

int main()
{
    int ans = 0;
    ms(rec, -1);
    cin >> r >> c;
    rep(i, 1, r)
        rep(j, 1, c)
            scanf("%d", &pic[i][j]);
    rep(i, 1, r)
        rep(j, 1, c)
            ans = max(ans, dfs(i, j)); //记录最大值
    cout << ans << endl;

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值