The King's Walk(dp)
题目链接:https://vjudge.net/problem/Kattis-kingswalk https://open.kattis.com/problems/kingswalk
题意:给你 n * n 的棋盘,两个点,从其中一个点开始走,在当前位置可以走到周围八个相邻的位置,问你走到另一个点的最短路径方案数,取模5318008。
思路:
1.两个点:(x1, y1), (x2, y2) ,dx = abs(x1 - x2), dy = abs(y1 - y2),最短路的长度一定是 max(dx, dy)。
2.通过交换坐标把两个点的相对位置变成这个样子

3.那么现在也就是说,从下面的点开始走,如果想要走出来的是最短路径的长度,那么每一步都要固定往上走,那么现在可以dp每一步的水平方向是向左,向右,还是不变,所以用dp[ i ][ j ] 表示走到第 i 行 j 列的方案数。
#include<bits/stdc++.h> #define inf 0x3f3f3f3f using namespace std; typedef long long ll; typedef unsigned long long ull; const int N = 5010; const int mod = 5318008; int n; int dp[N][N]; int main() { int t; int x1, y1, x2, y2; scanf("%d", &t); while(t--) { memset(dp, 0, sizeof(dp)); scanf("%d", &n); scanf("%d %d %d %d", &x1, &y1, &x2, &y2); int dx = abs(x1 - x2); int dy = abs(y1 - y2); if(dx > dy) { swap(x1, y1); swap(x2, y2); } int tot = max(dx, dy); // cout << x1 << " " << y1 << endl; // cout << x2 << " " << y2 << endl; // cout << tot << endl; dp[0][x1] = 1; for(int i = 1; i <= tot; i++) { for(int j = 1; j <= n; j++) { dp[i][j] = (dp[i - 1][j] + dp[i - 1][j - 1]) % mod; dp[i][j] = (dp[i][j] + dp[i - 1][j + 1]) % mod; // cout << i << " " << j << " " << dp[i][j] << endl; } } printf("%d\n", dp[tot][x2]); } return 0; }

浙公网安备 33010602011771号