J - The King‘s Walk dp求方案数

题目:https://vjudge.z180.cn/contest/425102#problem/J

题意: 求一个点到另一个点的最短距离的方案数, 有边界

/*

f(i, j) 表示从某一个点开始往上i层,并且位置是j的方案数

f(i, j) 可以由f(i - 1, j) 和 f(i - 1, j - 1) 和 f(i - 1, j + 1) 转移过来

因为他只能直着走或是斜着走,
 为什么他不能从他的旁边的点转移过来呢?
因为: 自己画画图就可以知道,这样的路径是更长的,不符合要求

即:f(i, j) = f(i - 1, j - 1) + f(i - 1, j) + f(i - 1, j + 1)
 
*/
#include <bits/stdc++.h>
#define lowbit(x) x&(-x)
using namespace std;
typedef pair<int, int > PII;
typedef long long ll;
const int mod = 5318008;
const int INF = 0x3f3f3f3f;
const int N = 5e3 + 50;

int n, f[2][N];

int main()
{
    
    
    int T; scanf("%d", &T);

    while (T--) {
    
    

        memset(f, 0, sizeof f);

        scanf("%d", &n);
        int x1, y1, x2, y2; scanf("%d%d%d%d", &x1, &y1, &x2, &y2);

        int m, x, y;

        int dx = abs(x1 - x2), dy = abs(y1 - y2);
        if (dx > dy) {
    
    
            m = dx, x = y1, y = y2;
        } else {
    
    
            m = dy, x = x1, y = x2;
        }

//        printf("---%d   %d %d\n", m, x, y);

        f[0][x] = 1;
        for (int i = 1; i <= m; i++) {
    
    
            for (int j = 1; j <= n; j++) {
    
    
                f[i & 1][j] = f[(i - 1) & 1][j];
                f[i & 1][j] += f[(i - 1) & 1][j - 1];
                f[i & 1][j] += f[(i - 1) & 1][j + 1];
                f[i & 1][j] %= mod;

            }
        }

        printf("%d\n", f[m & 1][y]);

    }

    return 0;
}

Guess you like

Origin blog.csdn.net/YingShen_xyz/article/details/114548195
J_S