樹形dp小結 2

2021-08-11 08:06:11 字數 2742 閱讀 9395

樹形dp的題一般都結合著揹包來用。以下的幾道題都是結合著揹包的思想來的

1:樹形dp+分組揹包     狀態比較難想

之前說過在最長距離的那道題裡說過,不會返回。但是有的提示需要考慮返回的節點的。

下面就是乙個例子:

題目大意:

給你乙個蘋果樹,有n個節點,每個節點上都有乙個乙個蘋果也就有乙個權值,當你經過這個點將得到權值,重複走節點只能算一次,給n-1條邊。問你走k步能得到的最大權值和。

dp[i][j][0]表示從i節點出發最後回到i節點花費最多j步能獲得的最大值, 

dp[i][j][1]表示從j節點出發最後不回到i節點花費最多j步能獲得的最大值 

dp[root][j][0] = max(dp[root][j-k][0] + dp[son][k-2][0])

//root->son 和 son->root 共花費2步,j-k是在其他兒子花費的步數

dp[root][j][1] = max(dp[root][j-k][0] + dp[son][k-1][1])

dp[root][j][1] = max(dp[root][j-k][1] + dp[son][k-2][0])

//只需要回到root一次,一種情況是先走其他兒子回到root再走son,

//另一種情況是先走son這個兒子並回到root再去走其他兒子

**:

#include #include #include using namespace std;  

const int m=210;

int wi[m];

int dp[m][m][2];//0不回來,1回來

int n,m;

int ne;

struct edge

edge[m*2];

int st[m];

void add_edge(int fr,int to)

int isu[m];

void dfs(int rt)

} }

}

int main()

dfs(1);

printf("%d\n",max(dp[1][m][0],dp[1][m][1]));

} return 0;

}

2:

hdu - 1561 

題目大意:

acboy很喜歡玩一種戰略遊戲,在乙個地圖上,有n座城堡,每座城堡都有一定的寶物,在每次遊戲中acboy允許攻克m個城堡並獲得裡面的寶物。但由於地理位置原因,有些城堡不能直接攻克,要攻克這些城堡必須先攻克其他某乙個特定的城堡。你能幫acboy算出要獲得盡量多的寶物應該攻克哪m個城堡嗎? 

思路分析:給你一棵樹,欲取子節點,必取父節點。問取的價值最多為多少。

簡單的樹形+揹包

**:

#include#include#include#include#define max 500

using namespace std;

vectorq[max];

int dp[max][max];

int v[max];

void dfs(int n,int m)

;int dp[155][155];

int brother[155];

int son[155];

int n,p;

void dfs(int r)

dp[r][1]=0;

for(int i=son[r];i!=-1;i=brother[i])

dp[r][j]=tmp;}}

}int main()

cout<4.揹包  +樹的重心變形

題目:tree cutting  poj2378

給乙個樹狀圖,有n個點。求出,去掉哪個點,使得剩下的每個連通子圖中點的數量不超過n/2。如果有很多這樣的點,就按公升序輸出。n<=10000 

思路分析:

此題是求解樹的重心的乙個變形。

根據求解樹的重心的方法,設f[i] 為 以i為根的子樹的結點個數,那麼 f[i] += 。

設dp[i] 為刪除結點i, 最大的連通圖有多少個結點。最後答案將d[i] <= n / 2 的結點 i 輸出即可。

**:#include#include#includeusing namespace std;

const int max=50010;

struct lalala //建結構體

edge[max*2];

int head[max];//前驅節點

int vis[max];//是否訪問過,做標記

int dp[max];//記錄擁有最大的節點數

int num[max];//統計以每個結點為根的樹的結點數,記為num.

int n, tot;

void add(int u, int v)//建樹

void init()

void dfs(int u)

dp[u]=max(dp[u],n-num[u]);

}int main()

dfs(1);

int ans[max];

int k=0;

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

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

}return 0;

}

a未完待續。。。。。。

樹形dp小結

這些天做了一些樹形dp的題目,感覺有了些領悟,尤其是理解到樹形揹包就是分組揹包之後。選出幾道不錯的總結一下 hdu 1520 hdu 4003 poj 1155 poj 2486 hdu 4313 hdu 4340 hdu 1520 入門水題 每個節點有權值,子節點和父節點不能同時選,問最後能選的最...

樹形DP 樹形DP四例

是時候練一下dp了!我的題單 portkey f u,if fu,i 表示以u uu為根節點的子樹中保留i ii條樹枝的最大蘋果數 f u,i max f max f fu,i max這些題是菜,但也不能輕視啊!include using namespace std define in read i...

HLOJ 樹形DP前置 DFS(樹形DP入門)

給定一棵 n nn 個點的樹,根為 t tt求每個點的父親是哪個點,t tt 的父親輸出 0 00第一行兩個整數 n,t n,tn,t接下來 n 1 n 1n 1 行,每行兩個整數 x,y x,yx,y,表示 x,y x,yx,y 之間有一條邊 n nn 行,第 i ii 行乙個整數,表示 i ii...