在n×n的棋盤裡面放k個國王,使他們互不攻擊,共有多少種擺放方案。國王能攻擊到它上下左右,以及左上
左下右上右下八個方向上附近的各乙個格仔,共8個格仔。
只有一行,包含兩個數n,k ( 1 <=n <=9, 0 <= k <= n * n)
方案數。
3 216
狀態壓縮dp第一道題。作為第一道題。其實對於我這種動態規劃都是自學的人來說。難度很大。但是。研讀各大神犇的標程和解析後。開始慢慢的明白了一些,所以這裡給一句忠告。沒什麼啃不下來的東西,如果啃不下來,那就多啃一會。
說起動態規劃。總是讓我想起一系列問題。什麼是狀態,怎麼轉移,怎樣決策。而這道題,好像沒怎麼用道決策。但是。什麼是狀態呢?怎麼樣在這道題實現轉移。這是值得思考的。不思考是沒有進步的。
而這道題讓我們一眼就可以想到dfs暴力列舉,以每個節點開始。列舉接下來每個點的位置。用二維陣列來模擬位置的擺放。dfs遞迴的其實可以打表出來。而這個方法潛在的狀態是上乙個點的「位置」。每次列舉的是「位置」。
這道題思考起來。關鍵:壓縮。當發現是這種二維,而且dfs要炸的題。首先考慮壓縮。降維?康托-壓縮狀態?。這裡想到的是,以一層為乙個狀態元素。而我們知道這個狀態有很多。因為最多就只有9*9,就9層。每一層有9個格仔。那麼我們可以提前預處理出來一層裡面每一種正確的擺放方式,如果這種方式正確則打上標記。這裡國王就只有擺或者不擺,很顯然我們可以想到有可以用二進位制來表示一層的狀態,這樣,一層就被我們壓縮成乙個數。一種可行性方案也被我們壓成了乙個數。
接下來的就是對於每一層進行遞推。我們都已經把每一種情況列舉出來。考慮每兩層之間的關係,dp轉移就成了列舉兩層的可能組合性,之後就是方案數的轉移。
這裡給出 f[i][q][j] (一種狀態) 其中這裡的i代表層數,這裡的j代表這一層如果是j這個狀態。q代表著一層及其以上的所有放的國王數量。這裡的j就指的是放的方式,舉個栗子 j==85 那麼那一層的方式就是 1010101(2)就是這樣der。
列舉每兩層方式。f [i] [q+cnt_1[a]] [a] += f[i-1] [q] [j];這個意思就是,如果上一層的擺放方式為j,這一層的擺放方式為a 那麼這一層放q+(a方式的擺放國王的數量)的狀態 是由 上一層擺放方式為j 擺放數量為q 的狀態轉移過來。(其中狀態裡存的是方案數)
#include#includeusing namespace std;
int cnt[512],map_1[512][512],cnt_1[512];
long long int f[10][512][512];
int n,k,all;
int first()
for(int i=0;i<=all;i++)if(cnt[i])
for(int j=0;j<=all;j++)if(cnt[j])
if( ((i&j)==0) && (((i>>1)&j)==0) && (((j>>1)&i)==0))
map_1[i][j]=1; //注釋2
return 0;
}int main()
{ scanf("%d%d",&n,&k);
all=(1《注釋:
1,這裡作用是判斷是否這種狀態是不是正確。
2,判斷兩種狀態能不能出線在一起(上下層)
3,這裡列舉q,因為每一層結合上一層還有這一層擺放的方式有很多,所以要考慮全面。
最重要的一條
不開long long見祖宗
不開long long見祖宗
不開long long見祖宗
不開long long見祖宗
不開long long見祖宗
不開long long見祖宗
BZOJ 1087 互不侵犯King(狀壓DP)
time limit 10 sec memory limit 162 mb submit 3984 solved 2323 submit status discuss 在n n的棋盤裡面放k個國王,使他們互不攻擊,共有多少種擺放方案。國王能攻擊到它上下左右,以及左上 左下右上右下八個方向上附近的各乙...
BZOJ 1087 互不侵犯King (狀壓dp)
time limit 10 sec memory limit 162 mb description 在n n的棋盤裡面放k個國王,使他們互不攻擊,共有多少種擺放方案。國王能攻擊到它上下左右,以及左上 左下右上右下八個方向上附近的各乙個格仔,共8個格仔。input 只有一行,包含兩個數n,k 1 n ...
BZOJ1087 互不侵犯king(狀壓DP)
題目大意 在n n 1 n 9 的棋盤裡面放k個國王,使他們互不攻擊,共有多少種擺放方案。國王能攻擊到它上下左右,以及左上左下右上右下八個方向上附近的各乙個格仔,共8個格仔 題解 看n的範圍1 n 9,大概就是狀壓dp了。把行的放法壓起來,狀態還是比較好想的。f i j now 表示前i行一共放了j...