過河卒
來源:洛谷
標籤:動態規劃
參考資料:
相似題目:
題目
棋盤上AA點有一個過河卒,需要走到目標BB點。卒行走的規則:可以向下、或者向右。同時在棋盤上CC點有一個對方的馬,該馬所在的點和所有跳躍一步可達的點稱爲對方馬的控制點。因此稱之爲“馬攔過河卒”。
棋盤用座標表示,AA點(0, 0)(0,0)、BB點(n, m)(n,m)(nn, mm爲不超過2020的整數),同樣馬的位置座標是需要給出的。
現在要求你計算出卒從AA點能夠到達BB點的路徑的條數,假設馬的位置是固定不動的,並不是卒走一步馬走一步。
輸入
一行四個數據,分別表示BB點座標和馬的座標。
輸出
一個數據,表示所有的路徑條數。
輸入樣例
6 6 3 3
輸出樣例
6
解題思路
馬走“日”字,首先生成馬的控制點。然後採用動態規劃思想,設dp[i][j]表示從(0, 0)到(i, j)的路徑個數,發現dp[i][j]=dp[i-1][j]+dp[i][j-1]。
參考代碼
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=25;
bool board[MAXN][MAXN];
long long dp[MAXN][MAXN];
int n,m;
int hn, hm; //馬的座標
int main(){
scanf("%d%d%d%d", &n, &m, &hn, &hm);
//生成馬的控制點
int dy[8]={-2, -2, -1, -1, 1, 1, 2, 2},
dx[8]={-1, 1, -2, 2, -2, 2, -1, 1};
board[hn][hm]=true;
for(int i=0;i<8;++i){
int y=hn+dy[i], x=hm+dx[i];
if(y>=0 && y<=n && x>=0 && x<=m){
board[y][x]=true;
}
}
//動態規劃過程
dp[0][0]=1;
for(int i=0; i<=n; ++i){
for(int j=0; j<=m ; ++j){
if(i-1>=0 && board[i-1][j]==false) dp[i][j]+=dp[i-1][j];
if(j-1>=0 && board[i][j-1]==false) dp[i][j]+=dp[i][j-1];
}
}
printf("%lld\n", dp[n][m]);
return 0;
}