BZOJ 1087 互不侵犯king

2022-08-18 22:48:18 字數 1277 閱讀 6641

這道題與皇后問題極像,只是兩者的攻擊範圍不一樣,同時根據題目限制可以發現,這道題資料的特殊性,棋盤很小,因此想到用狀態壓縮dp的方法求解。

首先將每一行互不侵犯的可能列出來,用1、0的方式記錄,之後根據要求會發現,每一行的情況受上一行的情況限制,於是從第一行進行一層層的判斷。又由於國王的攻擊是乙個九宮格,因此難點在於兩國王處於對角,則進行判斷時將下一行向左移一位或向右移一位再進行判斷。最後記得國王數是一定的,用乙個變數記錄一下。

程式無太大的突出,但每一步寫的較清晰,希望對大家有所幫助。

#include#include

#include

#include

#include

#define maxn 100 //

對maxn進行賦值 。

using

namespace

std;

long

long

int f[maxn]/*

行數*/[maxn]/*

狀態*/[600]/*

當前國王總數

*/,i_total/*

最終結果

*/;

intstay[maxn],cnt[maxn]; //

stay用於記錄每種狀態壓縮後的值。 cnt用於記錄對應的狀態中的1的個數。

int map[maxn]/*

i*/[maxn]/*

j*/; //

int i_side,i_number,i_temp=0; //

邊長、數量、每種狀態的個數。

void pre_dfs(int x,int y,int

z) //

預處理:x 是放了幾顆國王,y 是當前放的位置,z 是當前狀態壓縮後的值。

for(int i=y+2;i<=i_side;i++) //

用for迴圈重複所有可能,將每一種可能用遞迴進行記錄。

}void

pre_map()

} for(int i=1;i<=i_temp;i++)

}int

main()

for(int i_number=1;i_number<=i_temp;i_number++

}

}}

} for(int i=1;i<=i_temp;i++) //

計算最終值。

printf(

"%lld\n

",i_total); //

輸出結果。

return0;

}

BZOJ 1087, 互不侵犯

傳送門 給定一張大小為n n的棋盤,要求放置k個棋子,其中,棋子上下左右以及左上 左下 右上和右下八個位置不得有其它棋子存在。求合法方案數。動態規劃。狀態數很多,可以先預處理出一行的合法放置方案,再處理出上一行放置的情況下,下一行哪些方案是可行的,於是一行一行轉移即可。運用位運算優化預處理,後來四重...

BZOJ 1087( ) 互不侵犯

1087 scoi2005 互不侵犯king time limit 10 sec memory limit 162 mb submit 5333 solved 3101 submit status discuss description 在n n的棋盤裡面放k個國王,使他們互不攻擊,共有多少種擺放方...

BZOJ 1087 互不侵犯King

1087 scoi2005 互不侵犯king time limit 10 sec memory limit 162 mb description 在n n的棋盤裡面放k個國王,使他們互不攻擊,共有多少種擺放方案。國王能攻擊到它上下左右,以及左上 左下右上右下八個方向上附近的各乙個格仔,共8個格仔。i...