題意:給出乙個二叉樹,每條邊上有一定的邊權,並且剪掉一些樹枝,求留下 q 條樹枝的最大邊權和。 ( 節點數 n ≤100,留下的枝條樹 q ≤ n ,所有邊權和 ∑w[i] ≤30000 )
細節:對於一棵子樹 u 來說如果剪掉 u 節點上方的樹枝,則該子樹內的所有樹枝都相當於被剪去。
分析:由於是二叉樹,所以轉移就與左右子樹有關,其次我們需要求出最大的邊權和,而且需要記錄當前子樹保留了多少枝條。
所以 dp 的狀態:dp[u][j] 表示以 u 為根保留了 j 條樹枝(包括 u 的前一條樹枝)
轉移: dp[u][j] = max( dp[lx[u]][k] + dp[ly[u]][j-k-1] + pre[u], dp[u][j] ) lx[u]表示 u 的左子樹,ly[u]表示 u 的右子樹,pre[u]表示 u 的前一條邊
( j≤size[u],k≤min( size[lx[u]] , j-1) )size[u]表示以 u 為子樹的節點個數
**如下:
#include #define maxn 105using
namespace
std;
struct
edgeright[maxn
<<1
];int
begin[maxn], f[maxn][maxn], pre[maxn], size[maxn], n, q, cnt, lx[maxn], ly[maxn];
inline
void add_edge(int x, int y, int
z)void build(int u, int
fa)}
void solve(int u, int
fa)}
intmain()
build(
1, 0
);
for (int i=1; i<=n; i++) f[i][1]=pre[i];
solve(
1, 0
); printf(
"%d\n
", f[1][q+1
]);
return0;
}
二叉蘋果樹 樹形DP
題意 description 有一棵蘋果樹,如果樹枝有分叉,一定是分2叉 就是說沒有只有1個兒子的結點 這棵樹共有n個結點 葉子點或者樹枝分叉點 編號為1 n,樹根編號一定是1。我們用一根樹枝兩端連線的結點的編號來描述一根樹枝的位置。下面是一顆有4個樹枝的樹 2 5 3 4 1 現在這顆樹枝條太多了...
樹形DP 二叉蘋果樹
有一棵二叉蘋果樹,如果樹枝有分叉,一定是分兩叉,即沒有只有乙個兒子的節點。這棵樹共 n 個節點,編號為 1 至 n,樹根編號一定為 1。我們用一根樹枝兩端連線的節點編號描述一根樹枝的位置。一棵蘋果樹的樹枝太多了,需要剪枝。但是一些樹枝上長有蘋果,給定需要保留的樹枝數量,求最多能留住多少蘋果。這裡的保...
二叉蘋果樹(樹形DP)
原題 顯然我們考慮這道題目可以很蠢的寫乙個dp對吧。考慮 dp i,j 表示以i為根,保留j個節點的最大蘋果數。然後就可以樹形dp的寫了。include include include include include include include define ll long long defin...