动态规划 —— 树形 DP
【概述】
樹形動態(tài)規(guī)劃是在樹的數(shù)據(jù)結(jié)構(gòu)上的動態(tài)規(guī)劃,在各個階段呈現(xiàn)樹狀關(guān)系的時候可以采用樹形 DP,其基本思想是由子節(jié)點(diǎn)的信息推出父節(jié)點(diǎn)的信息。
樹形 DP 中,是通過以下 4 點(diǎn)樹的特點(diǎn)來進(jìn)行建圖的
【計(jì)算順序】
計(jì)算順序與線性動態(tài)規(guī)劃的順推、逆推相似,同樣有兩個方向:?
【表示方法】
樹形 DP 還涉及到建圖的問題,如果題目能很清晰的輸入一個樹,一般使用?vector<int> s[N],用 s[i] 來保存節(jié)點(diǎn) i 的所有兒子。
當(dāng)樹是一般樹且涉及到權(quán)值時,一般采用鏈?zhǔn)酱鎯Ψ?#xff0c;即用結(jié)構(gòu)體數(shù)組 edge 存邊,edge[i] 表示第 i 條邊,head[i] 存以 i 為起點(diǎn)的第一條邊(在edge中的下標(biāo))
struct Node{int next; //下一條邊的存儲下標(biāo)int to; //這條邊的終點(diǎn)int w; //權(quán)值 }edge[N*2]; //由于是無向圖,因此要開2倍常用的建圖方法如下
for(int i=1;i<=n;i++){int x,y;scanf("%d%d",&x,&y);addEdge(x,i);w[i]=y; }若以點(diǎn) i 為起點(diǎn)的邊新增了一條,則在 edge 中的下標(biāo)為 j,那么 edge[j].next=head[i],然后head[i]=j,即每次新加的邊作為第一條邊,最后倒序遍歷即可。
int cnt;//邊的計(jì)數(shù) void Add(int x,int y,int w) { //起點(diǎn)x, 終點(diǎn)y, 權(quán)值wedge[cnt].x=x;edge[cnt].w=w;edge[cnt].next=head[x];head[y]=cnt++; }遍歷以 x 為起點(diǎn)的邊時,以 i 開始為第一條邊,每次指向下一條(以-1為結(jié)束標(biāo)志)
memset(head,-1,sizeof(head)); for(int i=head[st]; i!=-1; i=edge[i].next){... }【計(jì)算方法】
樹形 DP 的計(jì)算方法則與線性 DP 不同,線性 DP 一般采用傳統(tǒng)迭代,而樹是通過遞歸定義的,因此樹形 DP 要遞歸來求解。
一般而言,樹形 DP 常與背包問題結(jié)合起來,常用 dp[node] 表示的是以 node 為根的子樹能得到的最優(yōu)解,dp[node] 需要從 node 的子結(jié)點(diǎn)進(jìn)行狀態(tài)轉(zhuǎn)移,由于 dp[node] 的狀態(tài)是由它的兒子轉(zhuǎn)移而來,因此可以 node 的 n 個兒子看做 n 個物品,對這 n 個物品抉擇得到最優(yōu)的 dp[node] 就用到背包的思想。
當(dāng)然,樹形 DP 不止 node 這一維,第二維一般都是以題目給出的限制需要來,然后根據(jù)題意保存好狀態(tài),寫出狀態(tài)轉(zhuǎn)移方程,遞歸的求解 DP[root]
【基本步驟】
1.若問題是一棵隱性樹(不以樹為直接背景,但各個階段呈樹狀關(guān)系),則需要將問題轉(zhuǎn)化為一棵顯性樹,并存儲各階段的樹狀聯(lián)系。
2.根據(jù)題目要求與數(shù)據(jù)量,選擇合適的樹的存儲方式。
若節(jié)點(diǎn)數(shù)小于5000,一般選用鄰接矩陣存儲;若節(jié)點(diǎn)數(shù)大于5000,一般選用鄰接表來存儲(邊要開到2*N,因?yàn)槭菬o向圖);若是二叉樹或需要多叉轉(zhuǎn)二叉,則可以用兩個一維數(shù)組 brother[N]、child[N] 來存儲。
3.寫出動歸方程
通過孩子和父親之間的關(guān)系建立方程,根據(jù)要求選用 根 => 葉 或 葉 => 根 的計(jì)算方式。
【題目類型】
1.常規(guī)問題
英文版:Anniversary party(HDU-1520):點(diǎn)擊這里
2.樹形背包問題
求在樹上選一些點(diǎn)滿足價值最大的問題,一般可設(shè) dp[i][j] 表示 i 這顆子樹選 j 個點(diǎn)的最優(yōu)解。
英文版:TELE(POJ-1115):點(diǎn)擊這里
3.刪點(diǎn)或刪邊問題
統(tǒng)計(jì)子樹和,通過加減一些子樹滿足題目中要求的某些性質(zhì)。
總結(jié)
以上是生活随笔為你收集整理的动态规划 —— 树形 DP的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 统计字符数(信息学奥赛一本通-T1187
- 下一篇: 石子合并问题--直线版(Hrbust-1