樹形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...