題意:
在乙個n行m列的棋盤上,讓你放若干個炮,可以是0個,使得沒有乙個炮可以攻擊另乙個炮,請問有多少種放置方法。
題解:因為每一行每一列的炮的數量<=2
考慮開dp陣列儲存有幾列放了乙個炮,有幾列放了兩個炮
dpi[k],表示放了前i行,有j列是有乙個棋子,有k列是有2個棋子的合法方案數
空的序列就是合法的,即m-j-k
接下來分類討論:
一、不放棋子
dpi[k]=dpi-1
[k]二、放乙個棋子
放在乙個棋子的列:
我們在某乙個有乙個棋子的列放置棋子,會使這一列變成有兩個棋子。
即我們要得到dpi
[k]需要在j+1個有乙個棋子的列放置棋子,變為有j個有乙個棋子的列
而我們有會得到新的有兩個棋子的列,因此我們之前必須有k-1個有兩個棋子的列。
放在沒有棋子的列:
在乙個沒有棋子的列放置棋子,會得到乙個新的有乙個棋子的列,即我們要從j-1得到j。
而這時候,我們有兩個棋子的列的數量不會變。可以在空列中的任何一列放置這個棋子。
即dpi
[k]+=dpi-1
[k-1]*(j+1)
dpi[k]+=dpi-1
[k]*(m-(j-1)-k)
三、放兩個棋子
乙個放在有乙個棋子的列,乙個放在沒有棋子的
都放在沒有棋子的列
都放在有乙個棋子的列
#includeusingnamespace
std;
const
int maxn=114
;const
int mod=9999973
;typedef
long
long
ll;int
n,m;
ll ans;
ll dp[maxn][maxn][maxn];
ll cal (
intx)
intmain () }}
for (int i=0;i<=m;i++)
for (int j=0;j<=m;j++)
ans+=dp[n][i][j],ans%=mod;
printf(
"%lld\n
",(ans+mod)%mod);
return0;
}
洛谷 P2051 中國象棋
orz stdcall 首先要想出來,每行最多只能放兩個棋子,這是顯然的 於是決策就是一行一行地處理 30分的做法就是裸的列舉,暴搜,列舉這一行放 放幾個 然後想到了壓位dp,按3進製表示當前棋盤的狀態,即某一列沒有棋子,或者有乙個,兩個棋子,能過50分 接著可以發現,棋子的順序是無所謂的,並不需要...
洛谷P2051 中國象棋
這次小可可想解決的難題和中國象棋有關,在乙個n行m列的棋盤上,讓你放若干個炮 可以是0個 使得沒有乙個炮可以攻擊到另乙個炮,請問有多少種放置方法。大家肯定很清楚,在中國象棋中炮的行走方式是 乙個炮攻擊到另乙個炮,當且僅當它們在同一行或同一列中,且它們之間恰好 有乙個棋子。你也來和小可可一起鍛鍊一下思...
洛谷 P2051 中國象棋 題解
題面 狀態可能不太好想,設f i j k 表示前i行其中有j行是放乙個炮,有k行是放兩個炮的合法方案數 那麼 f i 1 j k f i j k 在這一行不放任何棋子 f i 1 j 1 k f i j k m k j 在剩餘的m k j個空行中隨機選擇乙個放下乙個炮 f i 1 j 1 k 1 f...