題目大意:
在n行m列的棋盤上,放若干個炮可以是0個,使得沒有任何乙個炮可以攻擊另乙個炮。求有多少種放置方法?由於值比較大,輸出其mod 9999973的結果。
中國象棋中炮的行走方式大家應該很清楚吧。
100%的資料中n,m不超過100
50%的資料中,n,m至少有乙個數不超過8
30%的資料中,n,m均不超過6
題解:
dp:
題目可以發現,每一列最多放2個炮,所以可以做動規:
f[i,j,k]表示前i行j列放1個棋,k列放2個棋子的最大值。
所以對於到f[i,j,k]有6個情況:
1.不放棋子丨f[i-1][j][k]
2.放乙個棋子,放在之前沒有棋子的一列丨f[i-1][j-1][k]*(m-j-k+1)
3.放乙個棋子,放在之前有乙個棋子的一列丨f[i-1][j+1][k-1]*(j+1);
4.放兩個棋子,放在之前沒有棋子的兩列丨f[i-1][j-2][k]*c(m-j-k+2)
5.放兩個棋子,都放在之前沒有棋子的一列丨f[i-1][j][k-1]*(m-j-k+1)*j
6.放兩個棋子,分別放在之前沒有棋子和有乙個棋子的兩列丨f[i-1][j+2][k-2]*c(j+2)
c的操作是x*(x-1) div 2,這是某個很神奇的組合數操作….
var
f:array [-10..101,-10..101,-10..101] of longint;
ans,n,m,i,j,k:longint;
function
c(a:longint):longint;
begin
exit(a*(a-1) div
2);end;
begin
readln(n,m);
f[0,0,0]:=1;
for i:=1
to n do
for j:=0
to m do
for k:=0
to m-j do
begin
f[i,j,k]:=(f[i-1,j,k]+
f[i-1,j-1,k]*(m-j-k+1)+
f[i-1,j+1,k-1]*(j+1)+
f[i-1,j-2,k]*c(m-j-k+2)+
f[i-1,j,k-1]*(m-j-k+1)*j+
f[i-1,j+2,k-2]*c(j+2)) mod
9999973;
end;
for i:=0
to m do
for j:=0
to m-i do
ans:=(ans+f[n,i,j]) mod
9999973;
writeln(ans);
end.
luogu 2051 AHOI2009 中國象棋
這次小可可想解決的難題和中國象棋有關,在乙個n行m列的棋盤上,讓你放若干個炮 可以是0個 使得沒有乙個炮可以攻擊到另乙個炮,請問有多少種放置方法。大家肯定很清楚,在中國象棋中炮的行走方式是 乙個炮攻擊到另乙個炮,當且僅當它們在同一行或同一列中,且它們之間恰好 有乙個棋子。你也來和小可可一起鍛鍊一下思...
AHOI2009中國象棋
狀態很難想。本題難就難在如何定狀態。再看題解之前,我一點思路也沒有。看到題解的狀態表示後,我立刻知道怎麼做了。f i j k 表示至第i行,有j列放1個,有k列放2個。這樣f i j k 即為第i行不放 放1個 放2個的數量總和。狀態轉移方程很長,用到組合的相關知識。i 1時需特殊處理。詳見 inc...
AHOI2009 中國象棋
題目描述 這次小可可想解決的難題和中國象棋有關,在乙個n行m列的棋盤上,讓你放若干個炮 可以是0個 使得沒有乙個炮可以攻擊到另乙個炮,請問有多少種放置方法。大家肯定很清楚,在中國象棋中炮的行走方式是 乙個炮攻擊到另乙個炮,當且僅當它們在同一行或同一列中,且它們之間恰好 有乙個棋子。你也來和小可可一起...