P2051(動態規劃)

2021-09-23 08:17:22 字數 1489 閱讀 7921

這次小可可想解決的難題和中國象棋有關,在乙個n行m列的棋盤上,讓你放若干個炮(可以是0個),使得沒有乙個炮可以攻擊到另乙個炮,請問有多少種放置方法。大家肯定很清楚,在中國象棋中炮的行走方式是:乙個炮攻擊到另乙個炮,當且僅當它們在同一行或同一列中,且它們之間恰好 有乙個棋子。你也來和小可可一起鍛鍊一下思維吧!

基本思想就是放置其實與棋局所放置的形狀無關,直接對每一行進行討論就行了(我開始以為是八皇后問題的變種,但由於沒有斜行的約束條件,使得規劃起來比八皇后問題簡單很多,不用考慮之前行的棋盤形狀)

用dp[i][j][k]儲存第i行,j列乙個棋子,k列兩個棋子的方案數,每一行一共有6種放置方法(經過總結和合併後)

1

. dp[i-1]

[j][k] (i行不放棋子)

2. dp[i-1]

[j-1

][k]

*(m-k-j+

1) (放乙個棋子在空列處)

3. dp[i-1]

[j-2

][k]*(

(m-k-j+2)

*(m-k-j+1)

/2)(放兩個棋子在空列處)

4. dp[i-1]

[j+1

][k-1]

*(j+

1) (放乙個棋子在單棋子列)

5. dp[i-1]

[j+2

][k-2]

*((j+2)*

(j+1)/

2) (放兩個棋子在單棋子列)

6. dp[i-1]

[j][k-1]

*j*(m-j-k+

1) (放乙個棋子在單棋子列,乙個棋子在空列處)

#include

#define ll long long

#define int1 int

using namespace std;

int n,m;

const

int m=

9999973

;int x1=

2,x2=0;

ll dp[

105]

[105][

105]

;void

donggui

(int i,

int j,

int k)

void

initial()

intmain()

} x2+=2

; x1+=2

;}ll ans1=0;

for(

int i=

0;i<=m;i++)}

} cout<}

洛谷 P2051 中國象棋

orz stdcall 首先要想出來,每行最多只能放兩個棋子,這是顯然的 於是決策就是一行一行地處理 30分的做法就是裸的列舉,暴搜,列舉這一行放 放幾個 然後想到了壓位dp,按3進製表示當前棋盤的狀態,即某一列沒有棋子,或者有乙個,兩個棋子,能過50分 接著可以發現,棋子的順序是無所謂的,並不需要...

洛谷P2051 中國象棋

這次小可可想解決的難題和中國象棋有關,在乙個n行m列的棋盤上,讓你放若干個炮 可以是0個 使得沒有乙個炮可以攻擊到另乙個炮,請問有多少種放置方法。大家肯定很清楚,在中國象棋中炮的行走方式是 乙個炮攻擊到另乙個炮,當且僅當它們在同一行或同一列中,且它們之間恰好 有乙個棋子。你也來和小可可一起鍛鍊一下思...

洛谷P2051 中國象棋

題意 在乙個n行m列的棋盤上,讓你放若干個炮,可以是0個,使得沒有乙個炮可以攻擊另乙個炮,請問有多少種放置方法。題解 因為每一行每一列的炮的數量 2 考慮開dp陣列儲存有幾列放了乙個炮,有幾列放了兩個炮 dpi k 表示放了前i行,有j列是有乙個棋子,有k列是有2個棋子的合法方案數 空的序列就是合法...