随手练——洛谷-P1002 过河卒(动态规划入门)

题目链接:https://www.luogu.org/problemnew/show/P1002

题目还算良心,提醒了结果可能很大,确实爆了int范围,

这是一开始写的版本,用递归做的,先给地图做标记,每到一个点,这个点可以走的话,选择向下走还是向右走,但是会超时。

#include 
using namespace std;

int sign[23][23];
int M, N;
int res = 0;
void move(int i, int j) {
    if (i == N && j == M) {
        res++;
        return;
    }
    if (i < N&&sign[i + 1][j] != 1)
        move(i + 1, j);
    if (j < M&&sign[i][j + 1] != 1)
        move(i, j + 1);
}
void make_mark(int x, int y) {
    sign[x - 1][y - 2] = 1;
    sign[x - 1][y + 2] = 1;
    sign[x + 1][y + 2] = 1;
    sign[x + 1][y - 2] = 1;

    sign[x + 2][y - 1] = 1;
    sign[x + 2][y + 1] = 1;
    sign[x - 2][y - 1] = 1;
    sign[x - 2][y + 1] = 1;

    sign[x][y] = 1;
}

int main() {
    int x, y;
    cin >> N >> M >> x >> y;
    make_mark(x, y);
    move(0, 0);
    cout << res << endl;
    return 0;
}
View Code

然后改成了动态规划,手画个表就明白了,这是不考虑“马”的因素,到每个点的步数:

随手练——洛谷-P1002 过河卒(动态规划入门)_第1张图片

第一行,第一列可确定,其余的等于自己的左+上。

#include 
using namespace std;

int sign[23][23];
long long dp[21][21];
int M, N;

void make_mark(int x,int y) {
    sign[x - 1][y - 2] = 1;
    sign[x - 1][y + 2] = 1;
    sign[x + 1][y + 2] = 1;
    sign[x + 1][y - 2] = 1;

    sign[x + 2][y - 1] = 1;
    sign[x + 2][y + 1] = 1;
    sign[x - 2][y - 1] = 1;
    sign[x - 2][y + 1] = 1;

    sign[x][y] = 1;
}

int main() {
    int x, y;
    cin >> N >> M >> x >> y;
    make_mark(x, y);
    int flag = 1;
    for (int i = 0; i <= N; i++) {
        if (sign[i][0])flag = 0;
            dp[i][0] = flag;
    }
    flag = 1;
    for (int i = 0; i <= M; i++) {
        if (sign[0][i])flag = 0;
            dp[0][i] = flag;
    }

    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= M; j++) {
            if (sign[i][j] == 1) dp[i][j] = 0;
            else dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
        }
    }
    cout << dp[N][M] << endl;
    return 0;
}

 

转载于:https://www.cnblogs.com/czc1999/p/10361307.html

你可能感兴趣的:(随手练——洛谷-P1002 过河卒(动态规划入门))