日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

DFS与N皇后问题

發(fā)布時(shí)間:2025/3/21 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 DFS与N皇后问题 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

DFS與N皇后問題

DFS

什么是DFS

DFS是指深度優(yōu)先遍歷也叫深度優(yōu)先搜索

它是一種用來遍歷或搜索樹和圖數(shù)據(jù)結(jié)構(gòu)的算法

注:關(guān)于樹的一些知識(shí)可以去看《樹的概念及基本術(shù)語》這篇文章

它會(huì)不斷地沿著節(jié)點(diǎn)的深度方向(該深度方向?yàn)槠溧徑狱c(diǎn)的方向)進(jìn)行遍歷

DFS如何實(shí)現(xiàn)

DFS主要步驟有以下幾步

  • 訪問并從某節(jié)點(diǎn)
  • 向鄰接點(diǎn)出發(fā),訪問路徑向深處走
  • 若走到最深處還有節(jié)點(diǎn)沒訪問,則再回到該層訪問該節(jié)點(diǎn)(回溯)
  • 依次重復(fù)上述步驟,直至所有路徑都被訪問(遞歸)

DFS時(shí)空復(fù)雜度

空間復(fù)雜度

DFS算法實(shí)際上是一個(gè)遞歸算法,需要借助一個(gè)遞歸工作棧

  • 空間復(fù)雜度:O(n)

時(shí)間復(fù)雜度

  • 時(shí)間復(fù)雜度:不確定

為什么不確定?

因?yàn)楸闅v圖的過程實(shí)質(zhì)上是對(duì)每個(gè)頂點(diǎn)找查其所有鄰接點(diǎn)的過程,其耗費(fèi)時(shí)間取決于所采用結(jié)構(gòu)

下面給出常用的幾種數(shù)據(jù)結(jié)構(gòu)DFS時(shí)的時(shí)間復(fù)雜度

(注:n是圖中結(jié)點(diǎn)的個(gè)數(shù),e是圖中邊的個(gè)數(shù)。)

  • 鄰接表 O(e+n)
  • 鄰接矩陣 O(n^2)

N皇后問題

N皇后問題(HDU2553)

HDU 2553 N皇后問題在N*N的方格棋盤放置了N個(gè)皇后,使得它們不相互攻擊(即任意2個(gè)皇后不允許處在同一排,同一列,也不允許處在與棋盤邊框成45角的斜線上。 你的任務(wù)是,對(duì)于給定的N,求出有多少種合法的放置方法。輸入:共有若干行,每行一個(gè)正整數(shù)N≤10,表示棋盤和皇后的數(shù)量;如果N=0,表示結(jié)束。輸出:共有若干行,每行一個(gè)正整數(shù),表示對(duì)應(yīng)輸入行的皇后的不同放置數(shù)量。輸入樣例: 1 8 5 0輸出樣例: 1 92 10

經(jīng)典DFS帶來的問題

而經(jīng)典的DFS,基本是將所有子節(jié)點(diǎn)全部擴(kuò)展開,再選取最新的節(jié)點(diǎn)進(jìn)行擴(kuò)展。

但是對(duì)于N皇后來說,我們?nèi)绻灰幻杜e,則有N的N次方種情況.

即使N=10,則有10^10種情況,我們還要在這些情況中進(jìn)行篩選,這無疑需要巨大的計(jì)算

故:我們需要對(duì)DFS進(jìn)行優(yōu)化

回溯與減枝

我們可以讓程序在某節(jié)點(diǎn)由某些條件就可以判斷再進(jìn)行繼續(xù)展開并不符合要求,然后立即返回,達(dá)到回溯和減少樹的枝干的生成(減枝)的目的,從而進(jìn)行優(yōu)化。

下面給出N=4時(shí)減枝的樹狀圖解

問題分析

關(guān)鍵問題

關(guān)鍵問題:在擴(kuò)展節(jié)點(diǎn)時(shí)如何去掉不符合條件的節(jié)點(diǎn)?

設(shè)左上角是(0,0),已經(jīng)放好皇后是(i,j),不同行、列、斜線的新皇后是(r,c),則:

  • 橫向不同行 i != r
  • 縱向不同列 j != c
  • 斜對(duì)角:從(i,j)向斜對(duì)角走a步,新坐標(biāo)(r,c)有4種情況 (i-a,j-a) (i+a,j-a) (i-a,j+a) (i+a,j+a),即|i-r| = |j-c|。也就是說不再斜線上滿足 |i-r| != |j-c|

其他問題

  • 由于給出N<=10,所以可以用打表的方式,將每種n取值對(duì)應(yīng)的結(jié)果放到數(shù)組ans[n]中
  • 對(duì)于數(shù)組ans[]由于大小最方便設(shè)為11,n在0–10中取值一共11種情況。盡管我們可以忽略0定義成大小為10的數(shù)組(將n=1結(jié)果存放在ans[0]以此類推),但我們?cè)谌〕鰯?shù)據(jù)時(shí)還要進(jìn)行減法運(yùn)算并不方便。
  • 對(duì)于在對(duì)特定的n取值分析時(shí)可用個(gè)tot變量來記錄到達(dá)最深處情況的個(gè)數(shù),由于循環(huán)是從0開始,我們只需要讓r=n時(shí)tot自增1來記錄并回溯
  • 數(shù)組col[r] = c,表示皇后放在第r行c列,我們可以用col[i] 來依次獲得前幾行皇后位置信息,故對(duì)于本題col[]數(shù)組定義最大為10就行

題解代碼

#include <iostream>using namespace std;//tot記錄每次n取特定值能放置n皇后情況的個(gè)數(shù),每當(dāng)n改變時(shí)tot重置為0 int n, tot = 0;//表示皇后存放位置 col[r] = c 表示第r行的皇后在第c列 int col[10];//r為行,c為列 //check()用于檢查新放置的皇后(r,c)是否和已經(jīng)存放好的皇后沖突 //沖突返回false,不沖突返回true bool check(int r, int c) {for (int i = 0; i < r; i++)if (col[i] == c || (abs(col[i] - c) == abs(i - r))) //絕對(duì)值判斷是否在同一斜線上return false; //沖突返回falsereturn true; //不沖突返回true }//r為檢索的行 //對(duì)每行檢索并放置皇后 void DFS(int r) {//若達(dá)到最底行(層)則新增1種情況,并返回(回溯)if (r == n) {tot++;return;}//對(duì)第r行(層)的每一列進(jìn)行檢索,若能放置則進(jìn)入下一行(層)再從r+1行第0列向后檢索放置依次類推//若不能放置則本層次結(jié)束,遞歸然后回溯出去再改變上一層的列數(shù),從該列再進(jìn)行展開for(int c=0;c<n;c++)if (check(r, c)) //檢查若放在該層該列是否與之前皇后沖突{col[r] = c; //記錄再第r行c列放皇后,用于下一層向上檢驗(yàn)沖突DFS(r + 1); //繼續(xù)放下一層皇后}}int main() {//用于打表記錄結(jié)果的數(shù)組int ans[11];memset(ans, 0, sizeof(0));//算出n取所有值的答案for (n = 0; n <= 10; n++){memset(col, 0, sizeof(col)); //清空上一回的數(shù)組,計(jì)算下一個(gè)n皇后問題tot = 0;DFS(0);ans[n] = tot; //打表,保存}while (cin >> n){if (n == 0)return 0;cout << ans[n] << endl;}return 0; }

數(shù)據(jù)

下面給出n從1到10取值的數(shù)據(jù)以供參考

n取1的結(jié)果為:1 n取2的結(jié)果為:0 n取3的結(jié)果為:0 n取4的結(jié)果為:2 n取5的結(jié)果為:10 n取6的結(jié)果為:4 n取7的結(jié)果為:40 n取8的結(jié)果為:92 n取9的結(jié)果為:352 n取10的結(jié)果為:724

復(fù)雜度

以下對(duì)于本題解法而言

  • check()復(fù)雜度 O(n!)
  • DFS()復(fù)雜度 O(N)
  • 總復(fù)雜度 O(N!·N)

對(duì)于N>11且N<=15可用數(shù)據(jù)結(jié)構(gòu)舞蹈鏈較快解決

數(shù)學(xué)性質(zhì)

  • N皇后問題在數(shù)學(xué)上是個(gè)NP完全問題,不存在多項(xiàng)式時(shí)間算法

本文參考

  • 什么是Dfs? - 知乎 (zhihu.com)

  • DFS是什么意思?_百度知道 (baidu.com)

  • (3條消息) DFS時(shí)間復(fù)雜度_liuxiaocs7的博客-CSDN博客_dfs時(shí)間復(fù)雜度

  • dfs時(shí)間復(fù)雜度分析 - onlyblues - 博客園 (cnblogs.com)

  • (3條消息) DFS時(shí)間復(fù)雜度_liuxiaocs7的博客-CSDN博客_dfs時(shí)間復(fù)雜度

  • dfs時(shí)間復(fù)雜度分析 - onlyblues - 博客園 (cnblogs.com)

  • 《算法競(jìng)賽入門到進(jìn)階》—— 清華大學(xué)出版社

總結(jié)

以上是生活随笔為你收集整理的DFS与N皇后问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。