樹形DP——AcWing 323. 戰略游戲

樹形DP

定義

樹形動態規劃(Tree Dynamic Programming,簡稱樹形DP)是一種在樹形結構上應用動態規劃算法的技術。它利用樹的遞歸結構,通過定義狀態和狀態轉移方程,來求解與樹相關的最優化問題,如樹上的最長路徑、最小路徑覆蓋、最大獨立集等。與傳統的線性動態規劃相比,樹形DP更側重于利用樹的子結構特性,遞歸地解決問題,從葉子節點到根節點或反之進行狀態的累積和更新。

運用情況

  1. 樹的最長路徑問題:給定一個樹,找出一條路徑,使得該路徑上所有邊的權值之和最大。
  2. 數字轉換問題:在不超過 n 的正整數范圍內進行數字變換,求不斷進行數字變換且不出現重復數字的最多變換步數。
  3. 樹的中心問題:給定一棵樹,找到一個點,使得該點到樹中其他結點的最遠距離最近。
  4. 沒有上司的舞會問題:在一棵以校長為根的樹中,每個職員有一個快樂指數,且沒有職員愿意和直接上司一起參會,求邀請一部分職員參會使得所有參會職員的快樂指數總和最大。
  5. 路徑問題:如求解樹中兩個節點間的最大距離、樹的直徑等。
  6. 子樹問題:找出具有特定性質的子樹,如最大權獨立集、最小割集等。
  7. 計數問題:統計滿足特定條件的子樹數量,如完美子樹的數量、具有特定性質的路徑數量等。
  8. 優化問題:在樹上分配資源,使得某個指標最大化或最小化,如最小化涂色成本、最大化收集的資源等。

注意事項

  1. 樹形 DP 的 for 循環能優化就優化,比如取?j=min(size(x),m)k<=min(size(x),m)?之類的,否則很容易 TLE。
  2. 要考慮清楚不合法狀態是否會對答案產生影響,如果有就要?memset(dp,-1,sizeof(dp))?和初始化,樹形 DP 中跳過?dp(x)(j)=-1?和?dp(x)(k-j)=-1?之類情況。
  3. 狀態定義:正確定義狀態是關鍵,通常包括節點的選擇狀態(是否包含當前節點)和其他與問題相關的附加信息。
  4. 狀態轉移:明確狀態之間的依賴關系,設計合理的狀態轉移方程,通常從子節點到父節點進行信息傳遞。
  5. 邊界條件:處理好邊界情況,如樹的葉子節點或只有一個節點的子樹。
  6. 記憶化搜索:由于樹形DP往往涉及大量的重復計算,使用記憶化搜索可以避免重復計算,提高效率。
  7. 遞歸/迭代實現:根據具體情況選擇合適的實現方式,遞歸通常更直觀,迭代則可能在空間復雜度上有優勢。

解題思路

  1. 確定狀態表示:需要根據具體問題確定狀態表示,通常是以節點為基本單位,記錄每個節點的相關信息。
  2. 定義狀態轉移方程:根據問題的要求,確定狀態之間的轉移關系,即如何從一個狀態轉移到另一個狀態。
  3. 確定邊界條件:明確問題的邊界情況,例如根節點的狀態或者葉子節點的狀態。
  4. 進行遞歸計算:根據狀態轉移方程,從根節點開始遞歸地計算每個節點的狀態。
  5. 求解最優解:根據計算得到的狀態值,求解問題的最優解。
  6. 分析問題:首先明確問題的求解目標,識別出問題中的“最優子結構”,即問題的解可以由其子問題的解組合得出。
  7. 定義狀態:基于問題特點,定義狀態表示每個節點或子樹在求解過程中的信息,通常包括是否選擇該節點、子樹的某些屬性等。
  8. 設計狀態轉移方程:根據問題性質,確定狀態如何從子樹轉移到父節點,即如何通過子節點的信息計算出父節點的信息。
  9. 初始化:確定基礎情況,如葉子節點的初始狀態。
  10. 實現:使用深度優先搜索(DFS)或廣度優先搜索(BFS)遍歷樹,并根據狀態轉移方程計算每個狀態的值,通常使用記憶化或遞推實現。
  11. 回溯獲取答案:根據最終狀態,回溯獲得問題的最優解。

AcWing 323. 戰略游戲

題目描述

活動 - AcWingAcWing 323. 戰略游戲 - AcWing活動 - AcWing

?

?

運行代碼

#include <iostream>
#include <cstring>
using namespace std;
const int N = 2000, M = 4000;
int h[N], e[M], ne[M], idx;
int n;
int f[N][2];
int st[N];
void add(int a, int b)
{e[idx] = b; ne[idx] = h[a]; h[a] = idx ++;
}
void dfs(int u)
{f[u][1] = 1, f[u][0] = 0;for(int i = h[u]; ~i; i = ne[i]){int j = e[i];dfs(j);f[u][0] += f[j][1];f[u][1] += min(f[j][0], f[j][1]);}
}
int main()
{while(scanf("%d", &n) == 1){memset(h, -1, sizeof h);memset(st, 0, sizeof st);idx = 0;for(int i = 0; i < n; i ++ ){int id, cnt;scanf("%d:(%d)", &id, &cnt);while(cnt --){int ver;scanf("%d", &ver);add(id, ver);st[ver] = true;}}int root = 0;while(st[root]) root ++;dfs(root);printf("%d\n", min(f[root][0], f[root][1]));}return 0;
}

代碼思路

  1. 數據結構定義:

    • 使用鄰接表表示樹結構,其中h[N]是頭節點數組,e[M]是邊的終點數組,ne[M]是下一個兄弟節點的索引數組,idx用于記錄當前使用的邊的索引。
    • f[N][2]是一個二維狀態數組,其中f[u][0]表示以節點u為根的子樹中選擇不包含該節點的方案數,f[u][1]表示包含該節點的方案數。
    • st[N]標記數組,用來記錄某個節點是否已被其他節點直接連接過,輔助找到樹的根節點。
  2. 輸入處理:

    • 讀取整數n表示節點數量。
    • 接收每行輸入,格式為“節點ID:(直接子節點數量) 子節點1 子節點2 ...”,并構建鄰接表表示的樹結構。
  3. 尋找根節點:通過遍歷st[]數組找到沒有直接父節點的節點作為樹的根,初始化為0。

  4. 深度優先搜索(DFS):

    • 從根節點開始進行深度優先搜索,遞歸遍歷整棵樹。
    • 對于每個節點u,先假設自己不被選中(f[u][1]=1,表示以自己為根的子樹至少有一種情況是選中自己的),不選中父節點的方案數默認為0(f[u][0]=0)。
    • 遍歷所有子節點,遞歸調用DFS更新f[u][0]f[u][1]的值。f[u][0] += f[j][1]意味著考慮不選當前節點時,子節點可選擇不包含自己的方案數累加;f[u][1] += min(f[j][0], f[j][1])則是考慮選當前節點時,子節點可以自由選擇是否包含自己,取最小值是因為我們要找的是最小方案數。
  5. 輸出結果:最終,輸出根節點的f[root][0]f[root][1]中的最小值,即為滿足條件的最小方案數。

改進思路

  1. 增加注釋:提高代碼的可讀性,特別是對于復雜邏輯的部分,通過注釋說明每段代碼的目的。
  2. 變量命名清晰:使變量名更具描述性,便于理解每個變量的用途。
  3. 常量分離:將數組大小等硬編碼的常量提取為定義在頂部的常量,便于維護和修改。
  4. 函數封裝:將部分功能(如讀取樹的構建)封裝成獨立的函數,提高代碼模塊化。
  5. 去除全局變量的過度依賴:盡量減少全局變量的使用,使用函數參數傳遞必要信息。62.

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

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

相關文章

10秒教會你mysql的連接

連接MySQL數據庫通常可以通過多種方法實現&#xff0c;以下是幾種常見的方法&#xff0c;我將按照您的要求以清晰、分點的方式歸納說明&#xff1a; 1. 使用MySQL命令行客戶端 打開終端或命令提示符&#xff1a;首先&#xff0c;打開您的計算機上的終端或命令提示符窗口。輸入…

CSS中的display屬性:布局控制的關鍵

CSS的display屬性是控制元素在頁面上如何顯示的核心屬性之一。它決定了元素的顯示類型&#xff0c;以及它在頁面布局中的行為。本文將詳細介紹display屬性的不同值及其使用場景&#xff0c;幫助你更好地掌握布局控制。 display屬性的基本值 block 特點&#xff1a;塊級元素&…

LeetCode每日一題 2734.子串操作后的字典序最小字符串|標志位遍歷字符數組

問題描述 &#x1f4cb; 子串操作后的字典序最小字符串 給定一個僅包含小寫字母的字符串&#xff0c;你可以執行如下操作任意次&#xff1a; 選擇某個子串&#xff0c;將其中的每個字符都替換成其前一個字母&#xff08;比如 ‘b’ 變成 ‘a’&#xff0c;‘c’ 變成 ‘b’&…

未來數據中心智能運維的趨勢

隨著信息技術的飛速發展&#xff0c;數據中心作為支撐企業信息化建設的核心樞紐&#xff0c;其運維管理的重要性日益凸顯。傳統的運維模式已難以滿足現代數據中心高效、安全、靈活的需求&#xff0c;而智能運維正成為行業發展的新趨勢。本文將結合運維行業的資料和團隊經驗&…

【JavaScript 小工具】——如何判斷當前頁面是否在微信瀏覽器中打開

要判斷用戶是否通過微信瀏覽器打開網頁&#xff0c;你可以檢查用戶代理&#xff08;User Agent&#xff09;字符串中是否包含微信瀏覽器的特定標識。微信瀏覽器通常會在User Agent中包含"MicroMessenger"這個關鍵詞。 以下是一段JavaScript代碼示例&#xff0c;用于…

不使用cmake,如何在vs2019對cpp項目進行文件夾分類?

不使用cmake&#xff0c;如何在vs2019對cpp項目進行文件夾分類&#xff1f; 1.不使用cmake的根目錄指的是哪里&#xff1f;2.什么時候進行項目管理&#xff1f;3.應該分成什么樣的文件夾&#xff1f;4.如何分類&#xff1f; 1.不使用cmake的根目錄指的是哪里&#xff1f; 查看項…

最新AI智能聊天對話問答系統源碼(圖文搭建部署教程)+AI繪畫,文生圖,TTS語音識別輸入,文檔分析

一、人工智能語言模型和AI繪畫在多個領域廣泛應用 人工智能語言模型和AI繪畫在多個領域都有廣泛的應用。以下是一些它們的主要用處&#xff1a; 人工智能語言模型 內容生成 寫作輔助&#xff1a;幫助撰寫文章、博客、報告、劇本等。 代碼生成&#xff1a;自動生成或補全代碼&…

sudo: /etc/init.d/ssh: command not found

在 WSL 中嘗試啟動 SSH 服務時遇到 sudo: /etc/init.d/ssh: command not found 錯誤 安裝 OpenSSH 服務器 更新軟件包列表 sudo apt update安裝 OpenSSH 服務器 sudo apt install openssh-server啟動 SSH 服務 在 WSL 2 上,服務管理與傳統 Linux 系統有所不同。你可以手動啟動…

C++之STL(十)

1、適配器 2、函數適配器 #include <iostream> using namespace std;#include <algorithm> #include <vector> #include <functional>bool isOdd(int n) {return n % 2 1; } int main() {int a[] {1, 2, 3, 4, 5};vector <int> v(a, a 5);cou…

ONLYOFFICE 8.1版本桌面編輯器測評:重塑辦公效率的巔峰之作

在數字化辦公日益普及的今天&#xff0c;一款高效、便捷且功能強大的桌面編輯器成為了職場人士不可或缺的工具。ONLYOFFICE 8.1版本桌面編輯器憑借其卓越的性能和豐富的功能&#xff0c;成功吸引了眾多用戶的目光。今天&#xff0c;我們將對ONLYOFFICE 8.1版本桌面編輯器進行全…

使用el-amap-info-window遇到的問題

使用的這個庫https://github.com/yangyanggu/vue-amap 想要滾動amapInfoWindow里的內容&#xff0c;但不觸發地圖縮放 默認滾動amapInfoWindow里的內容&#xff0c;會觸發地圖縮放。看了C站一個大佬的文章解決了。 amapInfoWindow會自動滾動到頂部 我的amapInfoWindow里面用了…

【智能制造-4】機器人控制器

機器人控制器中分哪幾個模塊&#xff1f; 機器人控制器通常由以下幾個主要模塊組成: 運動控制模塊: 負責機器人各軸電機的位置、速度、加速度等控制 實現機器人末端執行器的精確定位和運動控制傳感器接口模塊: 負責機器人各種傳感器信號的采集和處理 為運動控制、環境感知等提…

Python-正則表達式

目錄 一、打開正則表達式 二、正則表達式的使用 1、限定符 &#xff08;1&#xff09;x*&#xff1a;*表示它前面的字符y 可以有0個或多個&#xff1b; &#xff08;2&#xff09;x&#xff1a;表示它前面的字符可以出現一次以上&#xff1b;&#xff08;只可以匹配多次&…

電鍍用開關電源技術詳解

1 引言 在電鍍行業里&#xff0c;一般要求工作電源的輸出電壓較低&#xff0c;而電流很大。電源的功率要求也比較高&#xff0c;一般都是幾千瓦到幾十千瓦。目前&#xff0c;如此大功率的電鍍電源一般都采用晶閘管相控整流方式。其缺點是體積大、效率低、噪音高、功率因數低、…

[CocosCreator]CocosCreator網絡通信:https + websocket + protobuf

環境 cocos creator版本&#xff1a;3.8.0 開發語言&#xff1a;ts 操作系統&#xff1a;windows http部分 直接使用 XMLHttpRequest 創建http請求 // _getHttpUrl 方法自己寫字符串拼接public httpPostJsonRequest(uri: string, headData: any, data: any, cb: Function…

2024年6月大眾點評深圳餐飲店鋪POI分析18萬家

2024年6月大眾點評深圳餐飲店鋪POI共有178720家 店鋪POI點位示例&#xff1a; 店鋪id G9TSD2JvdLtA7fdm 店鋪名稱 江味龍蝦館(南山店) 十分制服務評分 8.8 十分制環境評分 8.8 十分制劃算評分 8.6 人均價格 128 評價數量 12840 店鋪地址 南山大道與桂廟路交叉口西北角…

微信小程序 點擊左上角返回彈窗提示

業務需求&#xff1a;當頁面表單沒有提交直接返回時&#xff0c;要提示用戶是否保存當前信息&#xff0c;如果已經提交就不提示了。 由于微信小程序是無法監聽右上角按鈕返回事件。 所以就換個思路 小程序提供了如下兩個Api wx.enableAlertBeforeUnload(Object object)&…

Python入門-基礎知識-編程規范

1.縮進 在編程語言中&#xff0c;代碼之間往往存在著一定的邏輯關系和層次關系。C語言和Java語言等 用“{}”分隔代碼塊&#xff0c;而Python用的是縮進和冒號。Python代碼的縮進可以使用空格鍵或 Tab鍵來實現&#xff0c;通常情況下以4個空格或1個制表符作為1個縮進量。Pytho…

TCP協議中的三次握手和四次揮手機制

TCP協議中的三次握手和四次揮手機制 TCP&#xff08;Transmission Control Protocol&#xff0c;傳輸控制協議&#xff09;是一種面向連接的、可靠的、基于字節流的通信協議&#xff0c;它的三次握手和四次揮手機制是建立和斷開連接的關鍵步驟。 三次握手&#xff1a; 第一次…

等保測評與網絡安全法規的關聯:構建信息安全的法律與技術雙重保障

在信息化高速發展的今天&#xff0c;網絡安全已經成為國家安全、社會穩定和經濟發展的重要基石。為了保障網絡空間的安全和穩定&#xff0c;我國制定了一系列網絡安全法規&#xff0c;其中最為關鍵的就是《中華人民共和國網絡安全法》。與此同時&#xff0c;等保測評&#xff0…