洛谷P2051 中國象棋

2022-06-18 02:48:11 字數 1190 閱讀 1324

題意:

在乙個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)

三、放兩個棋子

乙個放在有乙個棋子的列,乙個放在沒有棋子的

都放在沒有棋子的列

都放在有乙個棋子的列

#includeusing

namespace

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...