- #include
- #include
- using namespace std;
-
- int board[20][20]; // 棋盘
- int dp[20][20][20][20]; // 动态规划数组
-
- int main() {
- int x0, y0, x1, y1;
- cin >> x0 >> y0 >> x1 >> y1; // 输入卒的起点和终点
-
- memset(board, 0, sizeof(board)); // 初始化棋盘
-
- // 初始化动态规划数组
- memset(dp, 0, sizeof(dp));
- dp[x0][y0][0][0] = 1;
- for(int i = x0; i <= x1; i++) {
- for(int j = y0; j <= y1; j++) {
- if(board[i][j] == 1) continue; // 如果该点有障碍物则跳过
- if(i > x0) dp[i][j][i-x0][0] += dp[i-1][j][i-x0-1][0]; // 上方的状态转移
- if(j > y0) dp[i][j][0][j-y0] += dp[i][j-1][0][j-y0-1]; // 左方的状态转移
- }
- }
-
- cout << dp[x1][y1][x1-x0][y1-y0] << endl; // 输出方案数
-
- return 0;
- }
其中,动态规划数组 dp[i][j][x][y] 表示从起点 (x0, y0) 到当前点 (i, j) ,沿途经过了 x 行、y 列,一共有多少种方案。初始状态为 dp[x0][y0][0][0] = 1,表示从起点出发,沿途未经过行或列的方案数为 1。
状态转移方程为:
- dp[i][j][x][y] = dp[i-1][j][x-1][y] (如果 i > x0 && board[i][j] != 1)
- + dp[i][j-1][x][y-1] (如果 j > y0 && board[i][j] != 1)
其中,board[i][j] 表示棋盘上点 (i, j) 是否有障碍物。如果该点有障碍物,则不能通过该点。最终,需要输出 dp[x1][y1][x1-x0][y1-y0]。