【Algorithm | 0x03 搜索與圖論】DFS

DFS

        • 基礎知識
        • 典型例題
          • 例1:n皇后問題
          • 例2:拍照
          • 例3:理發

基礎知識

核心原理:一條路走到黑

示意圖:其含義表示,在這個圖中頂層是第0層,也就是后面dfs的入口,一般從dfs(0)開始操作。

在這里插入圖片描述

模版:

#include <iostream>using namespace std;/*** DFS* 給定一個整數 n,將數字 1~n* 排成一排,將會有很多種排列方法。* 現在,請你按照字典序將所有的排列方法輸出。*/const int N = 10;
int n;
int path[N];    // 路徑
bool st[N];     // 元素是否訪問過void dfs(int u){// 當前記錄的數字個數到達n層 可以輸出一種情況了if (u == n){for (int i = 0; i < n; i++){printf("%d ", path[i]);}printf("\n");}//還可以繼續dfs搜索 這里的i是放的數值 從1~n嘛for (int i = 1; i <= n; i ++){// 如果當前層沒有被使用過if(!st[i]){path[u] = i;     //假設當前層放數值i進行嘗試st[i] = true;    //標記訪問過了dfs(u + 1);      //繼續下一層// 一定要恢復現場st[i] = false;}}
}int main(){cin >> n;dfs(0);  //從頂層也就是第0層開始return 0;
}
典型例題
例1:n皇后問題

非常經典的問題,指將n個皇后放在n * n的國際象棋棋盤上,任意兩個皇后不能處于同一行、同一列或同一斜線上。

我們的策略是一行一行的試,比如在第一行的時候,我們嘗試把第一個皇后放在所有列上的后續情況全部嘗試一邊,注意在這個過程中如果遇到不符合題目的情況需要及時剪枝。

在這里插入圖片描述

在判斷的過程中,除了行和列不能重復,最關鍵的是對角線的處理,這個分為對角線和反對角線,參考y = ax + b這條直線的截距進行理解
在這里插入圖片描述
在這里插入圖片描述

最終代碼:

#include <iostream>using namespace std;const int N = 20;
int n;
char g[N][N];   // 記錄方案 使用字符串記錄 
bool col[N], dg[N], udg[N];     // 標記  當前列是否放置過 當前對角線是否放置 當前反對角線是否放置 行不用考慮 因為dfs逐層下搜void dfs(int u){// 當前記錄的數字個數到達n層 可以輸出一種情況了if (u == n){for (int i = 0; i < n; i++){puts(g[i]);}printf("\n");}//還可以繼續dfs搜索 這里的i是放的列值 從0~n-1嘛   對角線怎么設置的for (int i = 0; i < n; i ++){// 如果當前列 對角線 反對角線沒有被使用過if(!col[i] && !dg[u + i] && !udg[n - u + i]){g[u][i] = 'Q';     //假設當前行u 的第i列可以放置col[i] = dg[u + i] = udg[n - u + i] = true;    //標記訪問過了  注意對角線dfs(u + 1);      //繼續下一層// 一定要恢復現場col[i] = dg[u + i] = udg[n - u + i] = false;g[u][i] = '.';}}
}int main(){cin >> n;for (int i = 0; i < n; i ++){for (int j = 0; j < n; j++){g[i][j] = '.';}}dfs(0);  //從頂層也就是第0層開始return 0;
}

方法2:每一個格子進行枚舉

這個的思想就是每個格子都嘗試一下能不能放皇后,遍歷所有情況。

在這里插入圖片描述

#include <iostream>using namespace std;const int N = 20;
int n;
char g[N][N];
bool row[N], col[N], dg[N], udg[N];// x 是行  y是列 s是當前擺下的皇后的個數
void dfs(int x, int y, int s){if (y == n){// 越界后 直接切換到下一行的第一個位置x ++;y = 0;}if (x == n){if (s == n){//完全擺完了 可以進行輸出for (int i = 0; i < n; i ++){puts(g[i]);}printf("\n");}return;   //這里一定要記得return 因為還沒完全結束所有情況}//正常走到這個格子了 下面就兩種操作 一個是放皇后 一個是不放// 嘗試不放 直接下一個// dfs(x, y ++, s);  這里太嚇人了  一定不能用這種自增 要不然就死循環了dfs(x, y + 1, s);// 嘗試放皇后 需要看能否放if (!row[x] && !col[y] && !dg[x + y] && !udg[x - y + n]){g[x][y] = 'Q';row[x] = col[y] = dg[x + y] = udg[x - y + n] = true;// 下一個// dfs(x, y ++, s ++);dfs(x, y + 1, s + 1);// 恢復現場row[x] = col[y] = dg[x + y] = udg[x - y + n] = false;g[x][y] = '.';}}int main(){cin >> n;for (int i = 0; i < n; i ++){for (int j = 0; j < n; j ++){g[i][j] = '.';}}// 0行 0列 也就是第一個格子  當前放置的皇后數為0;dfs(0, 0, 0);return 0;
}
例2:拍照

題面:小 A、小 B、小 C、小 D、小 E 五個人 拍照,我們會輸入一些前提條件,當id為1的時候,表示后面跟的兩個字母對應的人需要相鄰,id為2的時候,后面跟的兩個字母對應的人需要相隔,最終輸出多少種拍照方案

思考轉換:

轉換為dfs進行求解,就是把這5個人進行排序,比如先嘗試把A放在第一個位置,后面嘗試所有站位可能,在這個過程中,我們需要借助限制選項,比如相鄰還是相隔,可以實現提前剪枝,如果當前的站位方案不符合限制條件,也就是過不了我們的check函數,就直接剪掉。

最終代碼:

#include <iostream>using namespace std;/*** 小 A、小 B、小 C、小 D、小 E 五個人 * 轉換成dfs 就相當于5個人排位置  只不過添加了一些限制條件 進行剪枝*/// 整個結構體
struct limit{int id;char x, y;
}a[100];int res;
bool vis[105];
int path[1005];
int m;bool check(){// 遍歷檢查限制for (int i = 0; i < m; i ++){int id = a[i].id, x = a[i].x - 'A' + 1, y = a[i].y - 'A' + 1;// 這里一定要分清 位置和人物標號的關系int posx = 0, posy = 0;for (int i = 1; i <= 5; i ++){if (path[i] == x){posx = i;}if (path[i] == y){posy = i;}}// 這是要相鄰if (id == 1){// 思考 path[x] 代表的含義 我們應該找出第x個人所在的位置if (abs(posx - posy) > 1){return false;  //沒有相鄰}}// 必須不能相鄰if (id == 2){if (abs(posx - posy) == 1){return false;  //沒有相鄰}}}return true;
}
void dfs(int x){if (x == 5){if (check()){res ++;}   return;   // 當前結束,方案可能有多種,直接回退測試下一個方案}// 嘗試著5個人都放在當前位置for (int i = 1; i <= 5; i ++){if (!vis[i]){path[x] = i;   // 第x這個位置 放在第i個人vis[i] = true;dfs(x + 1);vis[i] = false;}}}int main(){cin >> m;for (int i = 0; i < m; i ++){cin >> a[i].id >> a[i].x >> a[i].y;}dfs(0);  // 從頂層 也就是第0層開始cout << res;return 0;
}
例3:理發

題面:

在這里插入圖片描述

思考轉換:這個轉換的思路在于選定一個標準進行dfs,因為先進行洗頭,所有人都要先洗頭,我們就把洗頭的順序作為dfs執行的標準,嘗試所有顧客開始洗頭的順序,洗頭確定之后,可以覆蓋所有組合情況,后面剪頭就只能按照實際情況進行,不斷更新記錄用時最短的方案。

最終代碼:

#include <iostream>
#include <queue>using namespace std;const int N = 11;
int a[N], b[N];  //洗發和剪發
int n;
int res = 1e9;   
int path[1005];
bool vis[105];// 首先可以明白 我們dfs的對象是什么 是洗頭的順序安排剩下的剪頭只能被迫安排
void dfs(int x){if (x == n){int y1 = 0, y2 = 0;   // 洗頭順序固定的情況下 尋找最短總時間priority_queue<int> q;for (int i = 0; i < n; i ++){int peo = path[i];  //第i個人y1 += a[peo];         // 第i個人洗發// 剪發時間 進入優先隊列q.push(b[peo]);y2 = max(y2, y1);  // y2是擔心之前還有人沒剪完頭int w = q.top();    //剪發 讀隊中頭 自動排序 最大的  讀完pop出隊q.pop();        y2 += w;   }res = min(y2, res);return;}for (int i = 0; i < n; i ++){if (!vis[i]){vis[i] = true;path[x] = i;   // 誰都有機會放在第一個 dfs(x + 1);vis[i] = false;}}
}int main(){int t;cin >> t;while (t --){cin >> n;res = 1e9;for (int i = 0; i < n; i ++){cin >> a[i] >> b[i];}dfs(0);cout << res << endl;}return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/94451.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/94451.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/94451.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Redis的數據過期策略有哪些?

Redis內部通過兩種主要策略來處理過期的Key&#xff1a; 惰性刪除 惰性刪除&#xff1a;顧明思議并不是在TTL到期后就立刻刪除&#xff0c;而是在訪問一個key的時候&#xff0c;Redis會先檢查這個鍵是否過期。如果過期&#xff0c;就刪除它&#xff0c;然后返回nil。 這種方式非…

水庫雨水情測報和大壩安全監測系統解決方案

一、方案背景 在全球氣候變化和極端天氣頻發的背景下&#xff0c;水庫作為重要的水利設施&#xff0c;承擔著防洪、供水、灌溉、發電等多重功能。然而&#xff0c;由于水庫蓄水量巨大&#xff0c;一旦發生潰壩或運行異常&#xff0c;將對下游地區造成不可估量的生命財產損失。因…

BFS 和 DFS 編程思想、框架、技巧及經典例題總結

BFS 和 DFS 編程思想、框架、技巧及經典例題總結 一、核心編程思想 BFS&#xff08;廣度優先搜索&#xff09; 核心思想&#xff1a;以「層次遍歷」為核心&#xff0c;從起點出發&#xff0c;優先探索距離起點最近的節點&#xff0c;逐層擴散遍歷。本質&#xff1a;通過「隊列」…

【面試場景題】日志去重與統計系統設計

文章目錄題目場景描述要求問題考察點解答思考一、核心解決方案&#xff08;基礎版&#xff0c;單節點32GB內存、10臺節點&#xff09;1. 整體架構選型2. 關鍵步驟詳解&#xff08;1&#xff09;數據分片&#xff1a;解決“數據量大&#xff0c;單節點處理不了”的問題&#xff…

【Day 16】Linux-性能查看

目錄 一、Stress系統壓力測試工具 二、性能查看 &#xff08;一&#xff09;查看CPU # nproc # lscpu # top # uptime # mpstat 數字1 數字2 &#xff08;二&#xff09;查看內存 # dmidecode -t memory | less # free -h # …

【ICCV2017】Deformable Convolutional Networks

一、摘要盡管卷積神經網絡&#xff08;CNN&#xff09;在視覺識別任務上取得巨大成功&#xff0c;但其固有的固定幾何結構&#xff08;固定卷積采樣網格、固定池化窗口、固定 RoI 劃分&#xff09;嚴重限制了對未知幾何變換&#xff08;尺度、姿態、形變、視角變化&#xff09;…

echarts在前后端分離項目中的實踐與應用

目錄 一、ECharts簡介 二、后端數據接口設計 三、數據結構設計 1. 柱狀圖數據結構 2. 餅圖數據結構 四、后端實現要點 五、前端ECharts配置解析 1. 柱狀圖配置 2. 餅圖配置 六、最佳實踐建議 七、總結 一、ECharts簡介 ECharts是百度開源的一個基于JavaScript的可視…

SQL 四大語言分類詳解:DDL、DML、DCL、DQL

SQL&#xff08;結構化查詢語言&#xff09;通常被分為四種主要類型&#xff0c;每種類型負責不同的數據庫操作。下面我將詳細介紹這四類SQL語言的語法和用途。一、DDL (Data Definition Language) 數據定義語言功能&#xff1a;定義和管理數據庫對象結構&#xff08;表、視圖、…

ESP-idf框架下的HTTP服務器\HTML 485溫濕度采集并長傳

項目描述:本項目采用485采集溫濕度以及電壓電流等,485模塊分別為下圖,串口轉485模塊采用自動收發模塊,ESP32工作在AP熱點模式,通過手機連接esp32的熱點來和esp進行數據通訊,使用esp32作為HTTP服務器缺陷:項目的最終HTML頁面代碼可發給AI讓其寫注釋#include "freertos/Free…

雅江工程解鎖墨脫秘境:基礎條件全展示(區位、地震、景點、天氣)

目錄 前言 一、區位信息 1、空間位置 2、區位介紹 二、地震信息 1、歷史地震信息 2、5.0級以上大地震 三、景點信息 1、景點列表分布 2、4A級以上景點 四、天氣信息 1、天氣實況 2、天氣應對挑戰 五、總結 前言 相信最近大家對雅江電站的超級大工程項目應該有所耳…

??機器學習貝葉斯算法

??一、引言??在當今機器學習領域&#xff0c;貝葉斯算法猶如一顆璀璨的明星。你是否想過&#xff0c;垃圾郵件過濾系統是如何準確判斷一封郵件是否為垃圾郵件的呢&#xff1f;這背后可能就有貝葉斯算法的功勞。今天&#xff0c;我們就一同走進貝葉斯算法的世界&#xff0c;…

Chisel芯片開發入門系列 -- 18. CPU芯片開發和解釋8(流水線架構的代碼級理解)

以【5 Stage pipeline CPU】搜索圖片&#xff0c;選取5幅有代表性的圖列舉如下&#xff0c;并結合Chisel代碼進行理解和點評。 圖1&#xff1a;原文鏈接如下 https://acsweb.ucsd.edu/~dol031/posts/update/2023/04/10/5stage-cpu-pipeline.html 點評&#xff1a;黑色的部分…

Docker容器中文PDF生成解決方案

在Docker容器中生成包含中文內容的PDF文件時&#xff0c;經常遇到中文字符顯示為方塊或亂碼的問題。本文將詳細介紹如何在Docker環境中配置中文字體支持&#xff0c;實現完美的中文PDF生成。 問題現象 當使用wkhtmltopdf、Puppeteer或其他PDF生成工具時&#xff1a; 中文字符…

2.java集合,線程面試題(已實踐,目前已找到工作)

1線程的創建方式 繼承Thread類實現Runnable接口實現Callable接口 2.這三種方式在項目中的使用有哪些&#xff0c;一般都是怎么用的 繼承thread類實現線程的方式通過實現run方法來實現線程&#xff0c;通過run進行線程的啟用實現runnable方法實現run方法&#xff0c;然后通過thr…

站在前端的角度,看鴻蒙頁面布局

從Web前端轉向鴻蒙&#xff08;HarmonyOS&#xff09;開發時&#xff0c;理解其頁面布局的相似與差異是快速上手的核心。鴻蒙的ArkUI框架在布局理念上與Web前端有諸多相通之處&#xff0c;但也存在關鍵區別。以下從五個維度系統分析&#xff1a; &#x1f4e6; 一、盒子模型&a…

JavaWeb遺傳算法、TSP、模擬退火、ACO算法等實戰應用

Java Web中實現遺傳算法的應用 以下是關于Java Web中實現遺傳算法的應用場景和實例的整理,涵蓋不同領域的解決方案和實現方法: 遺傳算法基礎結構 在Java Web中實現遺傳算法通常需要以下核心組件: 種群初始化:隨機生成初始解集。 適應度函數:評估個體優劣。 選擇操作:輪…

【圖像算法 - 09】基于深度學習的煙霧檢測:從算法原理到工程實現,完整實戰指南

一、項目背景與需求 視頻介紹 【圖像算法 - 09】基于深度學習的煙霧檢測&#xff1a;從算法原理到工程實現&#xff0c;完整實戰指南今天我們使用深度學習來訓練一個煙霧明火檢測系統。這次我們使用了大概一萬五千張圖片的數據集訓練了這次的基于深度學習的煙霧明火檢測模型&a…

間接制冷技術概念及特征

1、基本概念 (1)間接制冷技術即二次制冷技術。常規做法:二次冷卻液儲液罐增加放置于制冷系統管路,促使冷量再快捷的傳遞給載冷劑,繼而載冷劑冷量促使冷庫達到制冷效果。間接制冷技術:通過常壓的二次冷卻介質進行大循環傳送冷量,在直接制冷劑不易應用的位置或者不可運用直…

Antlr學習筆記 01、maven配置Antlr4插件案例Demo

文章目錄前言源碼插件描述pom引入插件案例&#xff1a;實現hello 標識符 案例1、引入Antlr4的pom運行依賴2、定義語義語法&#xff0c;配置.g4文件實現java代碼3、編寫完之后&#xff0c;執行命令實現編譯4、編寫單測測試使用參考文章資料獲取前言 博主介紹&#xff1a;?目前…

PostGIS面試題及詳細答案120道之 (101-110 )

《前后端面試題》專欄集合了前后端各個知識模塊的面試題&#xff0c;包括html&#xff0c;javascript&#xff0c;css&#xff0c;vue&#xff0c;react&#xff0c;java&#xff0c;Openlayers&#xff0c;leaflet&#xff0c;cesium&#xff0c;mapboxGL&#xff0c;threejs&…