洛谷 P1002 過河卒(動態規劃)
阿新 • • 發佈:2019-02-02
題目描述
棋盤上AA點有一個過河卒,需要走到目標BB點。卒行走的規則:可以向下、或者向右。同時在棋盤上CC點有一個對方的馬,該馬所在的點和所有跳躍一步可達的點稱為對方馬的控制點。因此稱之為“馬攔過河卒”。
棋盤用座標表示,AA點(0, 0)(0,0)、BB點(n, m)(n,m)(nn, mm為不超過2020的整數),同樣馬的位置座標是需要給出的。
現在要求你計算出卒從AA點能夠到達BB點的路徑的條數,假設馬的位置是固定不動的,並不是卒走一步馬走一步。
輸入輸出格式
輸入格式:
一行四個資料,分別表示BB點座標和馬的座標。
輸出格式:
一個數據,表示所有的路徑條數。
輸入輸出樣例
輸入樣例#1: 複製
6 6 3 3
輸出樣例#1: 複製
6
說明
結果可能很大!
題解:
沒看到這個說明真的好難受啊,WA了好幾次,結果資料量太大了,這種錯誤不能再犯了,改成 long long 就A了。
dp方程就是dp[i][j]=dp[i-1][j]+dp[i][j-1] (因為只能向右和向下走,從(0,0)這個點到另一個點(x,y)的走法的種數實際上就是dp[x-1][y]+dp[x][y-1]的值,就是點(x,y)左邊和上面的點的走法種類的加和)。
但是需要考慮邊界問題,當i=0或者j=0時,如果i-1或者j-1回出現負數,實際上當i=0或者j=0時dp[i][j]=d[i-1][j]或者dp[i][j]=dp[i][j-1];
#include<iostream> using namespace std; long long dp[1000][1000],vis[1000][1000]; void horse(int a,int b) { vis[a][b]=1; vis[a+2][b+1]=1; vis[a+1][b+2]=1; vis[a-1][b+2]=1; vis[a-2][b+1]=1; vis[a-2][b-1]=1; vis[a-1][b-2]=1; vis[a+1][b-2]=1; vis[a+2][b-1]=1; return ; } int main() { int n,m,x,y; cin>>n>>m>>x>>y; horse(x,y); dp[0][0]=1; for(int i=0;i<=n;i++) { for(int j=0;j<=m;j++) { if(vis[i][j]==0) { if(i==0&&j==0) continue; else if(i==0&&j!=0) dp[i][j]=dp[i][j-1]; else if(i!=0&&j==0) dp[i][j]=dp[i-1][j]; else dp[i][j]=dp[i-1][j]+dp[i][j-1]; } } } cout<<dp[n][m]<<endl; return 0; }