0
点赞
收藏
分享

微信扫一扫

记忆化DFS——How many ways?

A邱凌 2022-01-31 阅读 58

题目描述

 题目分析

问题可以转化为有一个矩阵,矩阵上每个点代表从这一步开始最多能走的步数,每次只能往右或者往下走,问从左上角到右下角有多少种方式。

因为每次走的时候不一定要把剩余步数走完,也是说在此前可以到达的点上可以重新选择一条路径。我们可以从左上角开始进行记忆化搜索,把每个点能到达右下角的路径数给记录下来,下次再到达这个点的时候就可以直接应用该数,从而极大减少时间复杂度。

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 110;
int mp[N][N], ans[N][N]; //mp存储图,ans存储从该点出发的路径数
int n, m, t;
int DFS(int x, int y) {
    if(ans[x][y] >= 0) return ans[x][y]; //记忆化搜索
    ans[x][y] = 0; //初始值
    for(int i = 0; i <= mp[x][y]; i ++) { //在能量允许范围内探索
        for(int j = 0; j <= mp[x][y] - i; j ++)
            if(x + i >= 1 && x + i <= n && y + j <= m && y + j >= 1) //检查越界
                ans[x][y] = (DFS(x + i, y + j) + ans[x][y]) % 10000;
    }
    return ans[x][y]; //返回答案
}
int main() {
    cin >> t;
    while(t --) {
        cin >> n >> m;
        memset(ans, -1, sizeof(ans)); //初始化
        for(int i = 1; i <= n; i ++)
            for(int j = 1; j <= m; j ++)
                cin >> mp[i][j];
        ans[n][m] = 1; //终点到终点,1种路径
        cout << DFS(1, 1) << endl;
    }
    return 0;
}
举报

相关推荐

0 条评论