求问此题记忆化搜索如何做?
查看原帖
求问此题记忆化搜索如何做?
1492214
yhmax楼主2025/1/16 18:06

rt.

本人记忆化搜索 60 pts.

#include <iostream>
#include <vector>
using namespace std;

const int MAXN = 21; // 由于 n, m <= 20
int n, m, horseX, horseY;
bool control[MAXN][MAXN]; // 控制点标记
int dp[MAXN][MAXN]; // 记忆化搜索数组

// 检查一个点是否是马的控制点
bool isControlPoint(int x, int y) {
    if (x < 0 || x > n || y < 0 || y > m) return true; // 超出边界
    if (x == horseX && y == horseY) return true; // 马所在点

    // 马的控制点
    int horseMoves[8][2] = {
        {1, 2}, {2, 1}, {2, -1}, {1, -2},
        {-1, -2}, {-2, -1}, {-2, 1}, {-1, 2}
    };

    for (int i = 0; i < 8; i++) {
        int nx = horseX + horseMoves[i][0];
        int ny = horseY + horseMoves[i][1];
        if (nx == x && ny == y) return true; // 马的跳跃控制点
    }

    return false;
}

// 记忆化搜索函数
int countPaths(int x, int y) {
    if (x > n || y > m) return 0; // 超出边界
    if (isControlPoint(x, y)) return 0; // 是控制点
    if (x == n && y == m) return 1; // 到达目标点

    if (dp[x][y] != -1) return dp[x][y]; // 如果已经计算过

    // 递归计算
    dp[x][y] = countPaths(x + 1, y) + countPaths(x, y + 1);
    return dp[x][y];
}

int main() {
    cin >> n >> m >> horseX >> horseY;

    // 初始化控制点标记
    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= m; j++) {
            control[i][j] = false;
        }
    }

    // 计算控制点
    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= m; j++) {
            if (isControlPoint(i, j)) {
                control[i][j] = true;
            }
        }
    }

    // 初始化 dp 数组
    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= m; j++) {
            dp[i][j] = -1; // -1 表示未计算
        }
    }

    // 计算路径数量
    int result = countPaths(0, 0);
    cout << result << endl;

    return 0;
}

2025/1/16 18:06
加载中...