DFS之剪枝與優化——AcWing 165. 小貓爬山

DFS之剪枝與優化

定義

DFS之剪枝與優化指的是在執行深度優先搜索(DFS, Depth-First Search)時,采取的一系列策略來減少搜索空間,避免無效計算,從而加速找到問題的解。剪枝是指在搜索過程中,當遇到某些條件不符合解的要求或者可以預判后續搜索不會產生有效解時,直接放棄這條搜索路徑,這一過程稱為剪枝。優化則是指通過調整搜索策略、順序等,提高搜索效率。

運用情況

  1. 組合優化問題:如全排列、組合總和、子集問題等,剪枝可以避免生成無效解。
  2. 圖的遍歷與搜索:在尋找特定路徑或計算連通分量時,剪枝可以減少搜索范圍。
  3. 游戲AI:如棋類游戲中預測對手可能的走法,剪枝減少計算量。
  4. 約束滿足問題:如數獨、任務調度等,剪枝幫助快速排除不滿足條件的解。

注意事項

  1. 剪枝條件的選擇:剪枝條件應嚴格且準確,避免誤剪有效解。
  2. 搜索順序:合理安排搜索順序,優先探索最有希望的分支。
  3. 狀態重置:回溯時確保正確恢復現場,避免狀態污染。
  4. 記憶化:對于重復子問題,使用記憶化技術存儲中間結果,避免重復計算。
  5. 資源管理:注意棧或遞歸深度限制,防止棧溢出。

解題思路

  1. 明確剪枝條件:分析問題特性,確定何時可以安全地剪枝。
  2. 優化搜索順序
    • 分支較少優先:優先探索分支較少的路徑,減少搜索深度。
    • 啟發式排序:依據某種評估函數排序待探索節點,優先探索最有潛力的節點。
  3. 可行性剪枝:在探索前,如果可以證明當前路徑無法導致有效解,立即剪枝。
  4. 最優性剪枝:在某些最優化問題中,如果已知當前路徑不能優于已找到的最佳解,剪枝。
  5. 迭代加深DFS:結合深度限制,逐步增加深度限制進行搜索,適用于尋找最短路徑等問題。
  6. 記憶化搜索:在適用場景下,利用動態規劃思想存儲中間結果,避免重復計算。

AcWing 165. 小貓爬山

題目描述

165. 小貓爬山 - AcWing題庫

運行代碼

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 20;int n, m;
int w[N];
int sum[N];
int ans = N;void dfs(int u, int k)
{if(k >= ans) return;if(u == n){ans = k;return;}for(int i = 0; i < k; i ++ )if(sum[i] + w[u] <= m){sum[i] += w[u];dfs(u + 1, k);sum[i] -= w[u];}sum[k] = w[u];dfs(u + 1, k + 1);sum[k] = 0;
}int main()
{cin >> n >> m;for(int i = 0; i < n; i ++ ) cin >> w[i];sort(w, w + n, greater<int>());dfs(0, 0);cout << ans << endl;return 0;
}

代碼思路

  1. 輸入與初始化:讀取小貓數量?n?和纜車最大承重?m,以及每只小貓的重量?w[],并按重量從大到小排序。
  2. DFS搜索:定義一個深度優先搜索函數?dfs(u, k),其中?u?是當前考慮的小貓索引,k?是當前已經考慮過的纜車數量。
    • 當搜索到的纜車數量?k?大于或等于已知的最小纜車數量?ans?時,提前結束此分支的搜索。
    • 當所有小貓都被考慮過后,更新最小纜車數量?ans
    • 對于每輛纜車,嘗試將當前小貓放入(如果總重不超過?m),遞歸搜索下一個位置的小貓。遞歸結束后回溯,撤銷選擇。
  3. 主函數邏輯:初始化數組?sum[]?用于記錄每輛纜車的當前載重,然后調用?dfs()?函數,最后輸出最小纜車數量?ans

其它代碼

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 20;int n, m;
int w[N];
int sum[N];
int ans = N;void dfs(int u, int k)
{if(k >= ans) return;if(u == n){ans = k;return;}for(int i = 0; i < k; i ++ )if(sum[i] + w[u] <= m){sum[i] += w[u];dfs(u + 1, k);sum[i] -= w[u];}sum[k] = w[u];dfs(u + 1, k + 1);sum[k] = 0;
}int main()
{cin >> n >> m;for(int i = 0; i < n; i ++ ) cin >> w[i];//sort(w, w + n, greater<int>());dfs(0, 0);cout << ans << endl;return 0;
}

代碼思路

  1. 變量定義:

    • n: 表示小貓的數量。
    • m: 表示每輛纜車的最大承重。
    • w[N]: 存儲每只小貓的重量。
    • sum[N]: 記錄每輛纜車當前的總重量。
    • ans: 初始設置為一個較大的數(N),用于記錄最少需要的纜車數量,最終會被更新為實際的最小數量。
  2. 主函數邏輯:

    • 讀取小貓數量?n?和纜車最大承重?m
    • 輸入每只小貓的重量?w[]。注意代碼中去掉了原先對w[]進行排序的部分,這在原始代碼中是為了優化搜索過程,因為通常按照重量從大到小處理可以更快達到最優解,但這里為了保持原始邏輯解釋,未進行排序。
    • 調用深度優先搜索函數?dfs(u, k)?進行求解,其中?u?表示當前考慮的小貓索引(從0開始),k?表示當前已經分配的纜車數量。
    • 輸出最少纜車數量?ans
  3. 深度優先搜索 (DFS) 函數邏輯:

    • 剪枝條件: 當已分配的纜車數量?k?大于等于已知的最小纜車數量?ans?時,直接返回,因為后續的搜索不會得到更好的解。
    • 終止條件: 當所有小貓都被考慮過(即?u == n)時,更新?ans?為當前的纜車數量?k,然后返回。
    • 嘗試分配小貓到已有纜車:
      • 遍歷之前的所有纜車(用?i?表示),檢查當前小貓是否能加入到纜車?i?中(即?sum[i] + w[u] <= m)。
        • 如果可以加入,就臨時增加?sum[i]?的值,然后遞歸調用?dfs?函數嘗試分配下一個貓,分配完后再恢復?sum[i]?的值(回溯)。
    • 嘗試分配到新纜車:
      • 將當前小貓分配到一個新的纜車(即?sum[k] = w[u]),然后遞歸調用?dfs?函數分配下一個貓,分配完后清空?sum[k](因為這是嘗試過程中的狀態,不是最終分配)。

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

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

相關文章

產科管理信息系統源碼:產科電子病歷、高危孕產婦五色管理系統源碼 孕產婦健康管理信息平臺源碼

產科管理信息系統源碼&#xff1a;產科電子病歷、高危孕產婦五色管理系統源碼 孕產婦健康管理信息平臺源碼 產科電子病歷系統是以采集病人在整個醫療護理過程中所產生的各種信息。包括病案首頁、門診病歷、住院病歷、出院記錄、病人病程記錄等全部病歷文書&#xff1b;涵蓋文字…

宿舍報修小程序的設計

管理員賬戶功能包括&#xff1a;系統首頁&#xff0c;個人中心&#xff0c;管理員管理&#xff0c;基礎數據管理&#xff0c;論壇管理&#xff0c;故障上報管理&#xff0c;新聞信息管理&#xff0c;維修人員管理 微信端賬號功能包括&#xff1a;系統首頁&#xff0c;新聞信息…

node.js外賣小程序-計算機畢業設計源碼81838

摘要 自從計算機發展開始&#xff0c;計算機軟硬件相關技術的發展速度越來越快&#xff0c;在信息化高速發展的今天&#xff0c;計算機應用技術似乎已經應用到了各個領域。在餐飲行業&#xff0c;除了外賣以外就是到店里就餐&#xff0c;在店里就餐如果需要等待點餐的話&…

轉盤輸入法-單獨鼠標版本

序 轉盤輸入法&#xff0c;給你的聊天加點新意。它不用常見的九宮格或全鍵盤&#xff0c;而是把字母擺在圓盤上&#xff0c;一滑一滑&#xff0c;字就出來了&#xff0c;新鮮又直接。 單獨鼠標版本GIF演示 演示軟件下載 轉盤輸入法https://download.csdn.net/download/u0146…

zdppy+vue3+antd 實現表格數據渲染

基本用法 <template><a-table :columns"columns" :data-source"data"><template #headerCell"{ column }"><template v-if"column.key name"><span>xxx Name</span></template></temp…

免費鼠標連點器有嗎?需要付費嗎?鼠標連點器電腦版免費推薦6款!

在數字化時代&#xff0c;鼠標連點器成為了許多用戶提高工作效率、優化游戲體驗的得力助手。然而&#xff0c;面對市場上琳瑯滿目的鼠標連點器軟件&#xff0c;很多用戶都會產生疑問&#xff1a;是否有免費的鼠標連點器&#xff1f;它們真的需要付費嗎&#xff1f;今天&#xf…

名企面試必問30題(二十二)——你對加班的看法?

1.思路 實際上&#xff0c;很多公司詢問此問題&#xff0c;并非表明一定要加班&#xff0c;只是想測試您是否愿意為公司奉獻。在回答時&#xff0c;一定不能有諸如不接受加班、不接受 996 等話語&#xff0c;因為沒有公司能承諾永遠不加班。主要回答應圍繞因何原因加班&#xf…

lua入門(1) - 基本語法

本文參考自&#xff1a; Lua 基本語法 | 菜鳥教程 (runoob.com) 需要更加詳細了解的還請參看lua 上方鏈接 交互式編程 Lua 提供了交互式編程模式。我們可以在命令行中輸入程序并立即查看效果。 Lua 交互式編程模式可以通過命令 lua -i 或 lua 來啟用&#xff1a; 如下圖: 按…

物理刪除和邏輯刪除區別

物理刪除和邏輯刪除是數據庫管理中針對記錄刪除操作的兩種不同方式&#xff0c;它們的主要區別在于數據的實際處理和后續影響&#xff1a; 物理刪除&#xff1a; 操作實質&#xff1a;物理刪除會將數據記錄從數據庫表中徹底移除&#xff0c;包括記錄所占的磁盤空間都會被釋放。…

Vue3 對跳轉 同一路由傳入不同參數的頁面分別進行緩存

1&#xff1a;使用場景 從列表頁跳轉至不同的詳情頁面&#xff0c;對這些詳情頁面分別進行緩存 2&#xff1a;核心代碼 2.1: 配置路由文件 在路由文件里對需要進行緩存的路由對象添加meta 屬性 // 需要緩存的詳情頁面路由 { name: detail, path: /myRouter/detail…

十大排序:插入/希爾/選擇/堆/冒泡/快速/歸并/計數/基數/桶排序 匯總(C語言)

目錄 前言非線性時間比較類插入排序(1) 直接插入排序(2) 希爾排序 選擇排序(3) 選擇排序優化版(4) 堆排序 交換排序(5) 冒泡排序(6) 快速排序hoare版本挖坑版前后指針版非遞歸版 歸并排序(7) 歸并排序遞歸版非遞歸版 線性時間比較類(8) 計數排序基數排序與桶排序 總結 前言 在計…

報文交換 和 電路交換對比說明

報文交換 和 電路交換 是兩種不同的網絡通信方式&#xff0c;它們在數據傳輸的方式、效率、成本和適用場景等方面有所不同。下面詳細對比這兩種交換方式&#xff0c;并舉例說明。 報文交換&#xff08;Message Switching&#xff09; 定義&#xff1a;報文交換是一種存儲-轉發…

昇思25天學習打卡營第13天|基于MindSpore通過GPT實現情感分類

基于MindSpore通過GPT實現情感分類 情感分類 情感分類是指在自然語言處理(NLP)領域中,通過分析文本內容所表達的情感傾向,將文本歸類為正面、負面或中性等類別的任務。 在情感分類中,基于不同的方法和技術,可以分為基于情感詞典的方法、基于傳統機器學習的方法和基于深…

c++筆試題

語言特性 題目1&#xff1a;請解釋C11中新引入的auto和decltype關鍵字&#xff0c;并給出使用示例。 題目2&#xff1a;什么是RAII&#xff08;Resource Acquisition Is Initialization&#xff09;&#xff1f;請解釋其原理并舉例說明。 題目3&#xff1a;C11引入了move se…

【unity實戰】使用舊輸入系統Input Manager 寫一個 2D 平臺游戲玩家控制器——包括移動、跳躍、滑墻、蹬墻跳

最終效果 文章目錄 最終效果素材下載人物環境 簡單繪制環境角色移動跳躍視差和攝像機跟隨效果奔跑動畫切換跳躍動畫&#xff0c;跳躍次數限制角色添加2d物理材質&#xff0c;防止角色粘在墻上如果角色移動時背景出現黑線條方法一方法二 墻壁滑行實現角色滑墻不可以通過移動離開…

Web貴州旅游攻略系統-計算機畢業設計源碼16663

目 錄 第 1 章 引 言 1.1 選題背景與意義 1.2 國內外研究現狀 1.3 論文結構安排 第 2 章 系統的需求分析 2.1 系統可行性分析 2.1.1 技術方面可行性分析 2.1.2 經濟方面可行性分析 2.1.3 法律方面可行性分析 2.1.4 操作方面可行性分析 2.2 系統功能需求分析 2.3 系…

前端面試題18(js字符串特定內容查找方法)

在JavaScript中&#xff0c;有多種方法可以用來查找字符串中的特定內容。以下是一些常用的方法&#xff0c;包括它們的用途和示例代碼&#xff1a; 1. indexOf() indexOf() 方法返回指定文本在字符串中第一次出現的索引&#xff08;位置&#xff09;&#xff0c;如果沒有找到…

初學者打字練習平臺推薦

大牛打字練習平臺 (ccfoj.com) 適合人群&#xff1a;c初學者&#xff0c;10~20歲不定&#xff0c;有效提高對代碼的熟悉程度&#xff0c;以及鍛煉打字速度。 TypingClub TypingClub是一個免費的在線打字練習平臺&#xff0c;提供各種打字練習內容&#xff0c;從基礎到高級。…

pulsar單節點能開啟事務嗎?是不是真的

Apache Pulsar 支持事務&#xff0c;但是需要在分布式模式下運行。單節點模式下不支持 Pulsar 事務。事務功能在 Pulsar 中依賴于分布式的 BookKeeper 存儲服務&#xff0c;以確保事務的持久性和可靠性。 具體來說&#xff1a; 分布式模式和事務支持&#xff1a; 在分布式部署…

MyBatis(26)MyBatis 有哪些方式可以實現多數據源管理

在企業級應用開發中&#xff0c;有時需要同時操作多個數據庫&#xff0c;這就涉及到多數據源管理的問題。MyBatis作為一個流行的持久層框架&#xff0c;本身并沒有直接提供多數據源管理的功能&#xff0c;但是可以通過與Spring等框架結合&#xff0c;或者通過自定義方式來實現多…