**馬踏過河卒**
problem description
棋盤上a點有乙個過河卒,需要走到目標b點。卒行走的規則:可以向下、或者向右。同時在棋盤上c點有乙個對方的馬,該馬所在的點和所有跳躍一步可達的點稱為對方馬的控制點。因此稱之為「馬攔過河卒」。棋盤用座標表示,a點(0,0)、b點(n,m)(n,m為不超過15的整數),同樣馬的位置座標是需要給出的。現在要求你計算出卒從a點能夠到達b點的路徑的條數,假設馬的位置是固定不動的,並不是卒走一步馬走一步。
input
一行四個資料,用空格分隔,分別表示b點的座標和馬的座標。
output
乙個資料,表示所有的路徑條數。
sample input
6 6 3 3
sample output
**
#includeint main()
; int b[9]= ; //馬的移動點
int n,m,x,y,i,j;
long long int f[20][20]= ; //到達某點的路徑數
int g[20][20]= ; //判斷是否是馬的控制點 1為控制 0為不控制
scanf("%d%d%d%d",&n,&m,&x,&y);
g[x][y]=1;
for(i=1; i<=8; i++) //找出所有控制帶點
if((x+a[i]>=0)&&(x+a[i]<=n)&&(y+b[i]>=0)&&(y+b[i]<=m))
for(i=1; i<=n; i++)
}for(j=1; j<=m; j++)
for(i=1; i<=n; i++)//遞推
}printf("%lld\n",f[n][m]);
return 0;
}
思路
思路如果用搜尋的方法,每乙個點都有向下向左兩種方案。2的24次方是1e8級別的,所以這種方法很不好。
如果沒有那些卒,從左上角到右下角是乙個經典的組合問題,方案數為c(n+m,n)/c(n+m,m)。
現在問題是在表中會有一些障礙,經過這些障礙的方案都將捨去,這時候我們用遞推的思想去解決。實際上,上面的組合數公式也是遞推得到的結果(組合數本身也有遞推方程):
由於卒只能向下或者向右走,那麼想要到達棋盤上的乙個點,有兩種方式:從左邊的格仔過來,或者從上邊的格仔過來。所以,過河卒到達某點的路徑數目等於到達與其相鄰的左邊點和上邊點的路徑數目和。我們用f(i,j) 來表示到達點 (i,j) 的路徑數目。所以遞推式為:f(i,j)=f(i-1,j)+f(i,j-1)。根據遞推式發現,可以用逐行或逐列的遞推方法求出從起點到終點的路徑數目。對於邊界條件,因為(0,0)是卒的起始位置,那麼f(0,0) = 1。
這樣先標記好障礙點,那麼障礙點這一定fi,j一定等於0,最終遞推得到的fn,m就是所求方案數了。
參考自部落格
馬踏過河卒
棋盤上a點有乙個過河卒,需要走到目標b點。卒行走的規則 可以向下 或者向右。同時在棋盤上c點有乙個對方的馬,該馬所在的點和所有跳躍一步可達的點稱為對方馬的控制點。因此稱之為 馬攔過河卒 棋盤用座標表示,a點 0,0 b點 n,m n,m為不超過15的整數 同樣馬的位置座標是需要給出的。現在要求你計算...
DP DFS,回溯 馬踏過河卒
題目描述 棋盤上a點有乙個過河卒,需要走到目標b點。卒行走的規則 可以向下 或者向右。同時在棋盤上c點有乙個對方的馬,該馬所在的點和所有跳躍一步可達的點稱為對方馬的控制點。因此稱之為 馬攔過河卒 棋盤用座標表示,a點 0,0 b點 n,m n,m為不超過20的整數 同樣馬的位置座標是需要給出的。現在...
遞推問題之馬踏過河卒問題
problem 棋盤上a點有乙個過河卒,需要走到目標b點。卒行走的規則 可以向下 或者向右。同時在棋盤上c點有乙個對方的馬,該馬所在的點和所有跳躍一步可達的點稱為對方馬的控制點。因此稱之為 馬攔過河卒 棋盤用座標表示,a點 0,0 b點 n,m n,m為不超過15的整數 同樣馬的位置座標是需要給出的...