NOIP專題複習(二) 八皇后與各種優化

2021-08-09 19:00:38 字數 1345 閱讀 5324

以八皇后為例來複習一下常見的幾種搜尋優化方法。

講真,我覺得,位運算優化的八皇后就是一道狀壓dp…

luogup1219

八皇后的核心是c[n]陣列,表示第n行在第c[n]個位置。

然後列舉一下1~n-1行即可。

另一大關鍵是如何判斷對角線,也很簡單,|c[n]-c[x]|=|n-x|

#include 

using

namespace

std;

#define maxn 14

int c[maxn],cnt,n;

void print()

cout

return

true;

}void dfs(int k)

for(int i=1;i<=n;++i)

}int main()

這樣會t乙個點。

不妨多開兩個陣列,分別維護兩個方向對角線的資訊。

這樣可以減少判斷次數。

考慮這個棋盤是具有對稱性的。

因此,對k皇后,

如果k是偶數,那麼我們可以只搜尋第一行的一半,從而減少運算量。

如果k是奇數,以n=13為例

1)第一行[1,6]與[8,13]是對稱的。

2)如果第一行放在第7個上,那麼顯然對於下一行,1)的分法是適用的,並且由於下一行不能放在第7個上,所以可以這樣列舉。

相當於減少了一半列舉數量。

用dp[i][j]表示第i行的狀態為j。這裡的j是乙個整數,其各個位表示的是某一格點是否存皇后。

比如,dp[5][173(10101101)]表示第5行時1、3、4、6、8列已經放過。

用rd,ld,row維護狀態的轉移。考慮一下,如果兩個皇后在同一豎直線,那麼顯然下一行左邊乙個位置、右邊乙個位置與正下的位置都是不合理的。所以狀態就可以轉移了。

#include

#include

#include

#include

using

namespace

std;

typedef

long

long ll;

ll ans,n,upperlim,qwq[14];

void print()

else dfs((ld+p)<<1,h+p,(rd+p)>>1,f+1);

}}else

}int main() {

cin>>n;

upperlim=(1

<1;

dfs(0,0,0,1);

cout

《參考:

luogu題解區各位神犇

演算法複習二 八皇后問題 回溯

一,問題描述 在8x8格的西洋棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行 同一列或同一斜線上,問有多少種擺法。二,分析 採用逐步試探的方式,先從乙個方向往前走,能進則進,不能進則退並嘗試另外的路徑。首先我們來分析一下西洋棋的規則,這些規則能夠限制我們的前進,也就是我們前進途中...

NOIP專題複習(一) 基礎的揹包問題

之所以要走這麼乙個專題原因也很簡單,在下的基礎實在是太薄弱了 所以接下來可能會變成非常基礎的題 略有難度的題和模板題並存的東西.於是就是這樣,就先從揹包開始吧 dp i j max dp i 1 j dp i 1 j w i v i 滾動陣列優化版 dp i max dp i dp i w i v ...

NOIP複賽複習(四)讀寫外掛程式與高精度模板

讀入輸出掛 讀入輸出掛就是逐個字元地讀入資料,從而讓讀入更加快速。輸出掛的原理也是一樣的,都是通過將輸出數字變成輸出字元以加快速度。當然輸入輸出外掛程式一般用在大量輸入輸出的情況下,這樣價效比才高一些,否則得不償失。void rd int res while p getchar p 0 void r...