二叉蘋果樹 二叉樹樹型DP

2022-06-01 07:39:09 字數 1243 閱讀 1376

傳送門

中文題面:

有一棵蘋果樹,如果樹枝有分叉,一定是分 2 叉(就是說沒有只有 1 個兒子的結點,這棵樹共有n 個結點(葉子點或者樹枝分叉點),編號為1-n,樹根編號一定是1。

我們用一根樹枝兩端連線的結點的編號來描述一根樹枝的位置。下面是一顆有 4 個樹枝的樹:

2 5

\ /3 4

\ /1

現在這顆樹枝條太多了,需要剪枝。但是一些樹枝上長有蘋果。

給定需要保留的樹枝數量,求出最多能留住多少蘋果。

第1行2個數,n 和q(1<=q<= n,1乙個數,最多能留住的蘋果的數量。

5 21 3 1

1 4 10

2 3 20

3 5 20

21
此題是選課的簡化版,因為規定了樹是一顆二叉樹,dp[i][j]表示以i為根節點的子樹選擇j條邊的最大值,因為是棵樹,所以可以將邊權轉移到點權上,剩下的就與選課一題異曲同工。

若選擇當前節點:

此節點是根節點的話,左右兒子一共分擔j個。列舉即可。

此節點不是根節點,左右兒子一共分擔j-1個。

若不選擇當前節點:dp = 0。

取較優值。

#includeusing namespace std;

const int n = 100;

int ecnt, adj[n + 5], go[n * 2 + 5], nxt[n * 2 + 5], val[n + 5], len[n * 2 + 5];

int fa[n + 5], ch[n + 5][2];

typedef long long ll;

ll dp[n + 5][n + 5];

int n, m;

inline void addedge(int u, int v, int c)

inline void dfs(int u, int f)

}inline ll dp(int u, int k)

return dp[u][k];

}int main()

dfs(1, 0);

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

dp(1, m);

cout << dp[1][m] << endl;

return 0;

}

二叉蘋果樹 樹型DP 揹包

二叉蘋果樹 有一棵蘋果樹,如果樹枝有分叉,一定是分2叉 就是說沒有只有1個兒子的結點 這棵樹共有n個結點 葉子點或者樹枝分叉點 編號為1 n,樹根編號一定是1。我們用一根樹枝兩端連線的結點的編號來描述一根樹枝的位置。下面是一顆有4個樹枝的樹 2 5 3 4 現在這顆樹枝條太多了,需要剪枝。但是一些樹...

二叉蘋果樹

我們可以把保留邊轉換成保留點 因為我個人對保留點熟 跟據樹的性質,乙個點有0or1個根。所以我們可以把邊上的蘋果數轉移到子節點上。根據題意可知這應是一道dp題 廢話 設f i j 為以i為根的樹上保留j個節點的最大權值和,又因為這是個二叉樹,所以我們不妨設左子樹要保留的節點數為k,那麼右子樹的需要保...

二叉蘋果樹

有一棵二叉樹,每條樹枝上有乙個權值,求保留 q 個樹枝下能達到的最大權值。我們考慮 n 較小,先把邊轉化為點,我們可以用 f i j 表示以 i 為根的子樹中選 j 個節點的能達到的最大權值,那麼有三種情況 1 左子樹全部砍掉。2 右子樹全部砍掉。3 左子樹保留 k 個,右子樹保留 j k 個節點,...