樹形DP學習總結

2021-09-25 21:02:26 字數 1823 閱讀 9368

概述

樹形dp是dp的一種,有時候會和區間dp結合。

由於樹有著天然的遞迴結構 父子結構 而且它作為一種特殊的圖 可以描述許多複雜的資訊 因此在樹就成了一種很適合dp的框架

問題:給你一棵樹 要求用最少的代價(最大的收益)完成給定的操作

樹形dp 一般來說都是從葉子從而推出根 當然 從根推葉子的情況也有 不過很少

一般實現方式: dfs(包括記憶化搜尋) 遞推等

一般實現:

void dfs(int rot)

}

題目

洛谷p1040

這個題不僅是樹形dp(主要是遍歷),還是個區間dp,一般題目給出樹的中序遍歷,都是區間dp+樹形dp。

中序遍歷一般都是通過列舉l,r區間的根來進行區間dp的。

**:(這個是很久以前寫的,比較醜)

#include using namespace std;

const int n = 37;

int n,a[n],m[n][n],root[n][n];

//遍歷整個樹

int dfs(int i, int j)

} return m[i][j] = ans;

}//前序遍歷輸出根

int prt(int l,int r)

printf("%d ",root[l][r]);

prt(l , root[l][r]-1);

prt(root[l][r]+1 , r);

}int main()

洛谷p1122 最大子樹和

看題目,非常模板的樹形dp,注意因為不一定選的是包含根節點的一段,所以答案不在根節點上,每次要max更新ans。

**:

#include using namespace std;

const int n = 16007;

int n,a[n],f[n],ans;

bool vis[n];

vector g[n];

void dfs(int x)

}int main()

dfs(1);

printf("%d\n",ans);

return 0;

}

洛谷p1352 沒有上司的舞會

也是很模板的樹形dp,不過轉移方程要想一下,如果上司選了,下司一定不能選,如果上司沒選,下司可以選也可以不選。

**:(也是很久之前寫的了,略醜)

#include using namespace std;

const int n = 6e3 + 7;

int n;

int f[n][2];

struct ed

edge[n];

int dfs(int root)

}int main()

int t1,t2,rt;

scanf("%d %d",&t1,&t2);

for(int i = 1; i <= n; i++)

f[i][1] = edge[i].w;

//找rot dp起點

for(int i = 1; i <= n; i++)

if(!edge[i].fa) rt = i;

dfs(rt);

printf("%d\n",max(f[rt][1],f[rt][0]));

return 0;

}

三道題,不同年**的,寫了三種存樹的方式,我也是佩服我自己。

未完待續

2023年8月4日

樹形dp總結

from 列出一些經典問題吧 1 給出一棵樹 每個節點有權值 要求父節點和子節點不能同時取 求能夠取得的最大值 hdu1520 2 給出一棵樹,求離每個節點最遠的點的距離 hdu2196 3 1 在乙個地圖上,有n座城堡,每座城堡都有一定的寶物,在每次遊戲中允許攻克m個城堡並獲得裡面的寶物。但由於地...

樹形dp總結

這個月一直搞dp了,狀壓,數字,樹形,感覺雖然有時訓練很辛苦,但真的很充實。這個星期看了一些樹形dp的資料。樹形dp簡單來說就是在樹上的dp,這裡的很多題,都和揹包有聯絡,從乙個根節點開始,分配方案給它的子樹。有乙個很有意思的題。沒有上司的聚會 hdu 1520 大致題意就是說,要舉辦乙個聚會,每個...

樹形DP總結

換根 fat結點更新u結點子結點 dp fat ans fat max dp u 0 老方法 更新根節點 ans u dp u max dp fat 0 第一次dfs 回溯時處理子結點為u向下的簡單路徑第一大和第二大 第二次dfs 遞迴處理子結點為u向上的簡單路徑最大 const int n 5e5...