互不侵犯(洛谷P1896)

2022-02-02 04:40:07 字數 1210 閱讀 4953

題目:在n*n的棋盤裡面放k個國王,使他們互不攻擊,共有多少種擺放方案。國王能攻擊到它上下左右,以及左上左下右上右下八個方向上附近的各乙個格仔,共8個格仔。

輸入輸出:輸入n,k,輸出有幾種放置方法。(n<=9,k<=n^2)

樣例輸入輸出:

入:3 2

出:16

這道題看範圍就顯然是狀壓dp了吧。。。

其實這道題和狀壓基礎題玉公尺地(corn fields)非常相像,主要思路包括以下幾點。

1.同一行不能有相鄰的國王。

2.斜對角和正上正下不能有相鄰的國王。

3.一共只有k個國王。

根據狀壓dp的一般尿性,肯定是要列舉狀態的,那狀態裡面「 1 」,「 0 」表示什麼含義呢?

肯定是「 1 」表示這一行這個位置放國王,「 0 」表示不放啊(廢話++)

那思路就挺顯然了。

1.列舉狀態s,判斷(s&(s<<1))==0,只有這樣的s才是合法狀態

2.列舉上一行狀態s,判斷((s&(s<<1))==0&&(s&(s>>1))==0&&(s&s)==0)分別對應右上,左上,正上。

3.主要麻煩的是這個k,怎麼處理已經放了多少國王呢,這裡我們可以用類似揹包的思想,新開一維表示已經放入的國王數,然後由上一行較少國王數的狀態轉移過來(是不是很像揹包的二維**那個轉移?可以把國王總數看作揹包的容量,每乙個國王就是揹包中的乙個個物品)

然後就沒了。。。

附上全部**:

#include#include

#include

#include

using

namespace

std;

const

int maxn=1e2+10

;typedef

long

long

ll;ll f[

15][1

<<10][80

];int lowbit(int x)

int find(int

x)

return

cnt;

}int

main()

}

} }}

ll ans=0

;

for(int s=0;s<=max;s++)

printf(

"%lld

",ans);

return0;

}

洛谷P1896 互不侵犯 狀壓dp

在n n n nn n的棋盤裡面放k kk個國王,使他們互不攻擊,共有多少種擺放方案。國王能攻擊到它上下左右,以及左上左下右上右下八個方向上附近的各乙個格仔,共8 88個格仔。n 9 k n n n 9,k n n n 9 k n n 首先暴搜肯定被否定,時間複雜度是指數級的,所以我們就可用上狀態壓...

洛谷 1896 互不侵犯

在n n的棋盤裡面放k個國王,使他們互不攻擊,共有多少種擺放方案。國王能攻擊到它上下左右,以及左上左下右上右下八個方向上附近的各乙個格仔,共8個格仔。注 資料有加強 2018 4 25 只有一行,包含兩個數n,k 1 n 9,0 k n n 所得的方案數 輸入 1複製 3 2 輸出 1複製 16 題...

P1896 互不侵犯 狀壓DP

目錄題目 分析變數定義 剔除左右相鄰的狀態 計算king state 如何動態規劃?如何表示限制條件 原博主的 寫在最後 在n n的棋盤裡面放k個國王,使他們互不攻擊,共有多少種擺放方案。國王能攻擊到它上下左右,以及左上左下右上右下八個方向上附近的各乙個格仔,共8個格仔。輸入格式 只有一行,包含兩個...