樹形動態規劃

2021-06-07 11:30:57 字數 1323 閱讀 4354

description

有一棵蘋果樹,如果樹枝有分叉,一定是分2叉(就是說沒有只有1個兒子的結點)

這棵樹共有n個結點(葉子點或者樹枝分叉點),編號為1-n,樹根編號一定是1。

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

2 5\ /

3 4\ /

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

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

input

第1行2個數,n和q(1 <= q <= n,1 < n <= 100)。

n表示樹的結點數,q表示要保留的樹枝數量。接下來n-1行描述樹枝的資訊。

每行3個整數,前兩個是它連線的結點的編號。第3個數是這根樹枝上蘋果的數量。

每根樹枝上的蘋果不超過30000個。

output

乙個數,最多能留住的蘋果的數量。

sample input

5 21 3 1

1 4 10

2 3 20

3 5 20

sample output21

分析:這題的權值在邊上,這在思考時有些彆扭,其實只要把邊的權值轉移到兒子結點上,問題性質不變。

這樣狀態就應該容易想到了,f[i][j]表示以i結點為根的子樹保留j個結點所得的最大值。因為根結點沒有權值,所以我們要保留p+1個點。

f[i][j]=max{f[i_left][k]+f[i_right][j-1-k]}   (0<=k<=j-1)

邊界 f[i][0]=0;f[i][1]=value[i]

最後f[1][p+1]就是答案

為什麼是j-1-k,而不是j-k呢?這是因為要保留以i為根的j個節點,而i已經佔了乙個節點了,所以孩子節點只能再保留j-1個節點了。

#include#include#includeusing namespace std;

struct node

tree[220];

bool vis[110];

int n,q;

void make_tree(int root)//一旦涉及到樹的操作,遞迴總是會簡化很多**

}int tree_dp(int t,int k)

f[t][k]=0;

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

;vectoradj[maxn];

void init( )}}

}if (left==1) return;

}int main( )

return 0;

}

以上參考:

樹形動態規劃

分類 演算法 2012 07 01 21 53 494人閱讀收藏 舉報tree output input struct演算法 description 有一棵蘋果樹,如果樹枝有分叉,一定是分2叉 就是說沒有只有1個兒子的結點 這棵樹共有n個結點 葉子點或者樹枝分叉點 編號為1 n,樹根編號一定是1。我...

樹形動態規劃

問題可以分解成若干相互聯絡的階段,在每乙個階段都要做出決策,全部過程的決策是乙個決策序列。要使整個活動的總體效果達到最優的問題,稱為多階段決策問題。動態規劃就是解決多階段決策最優化問題的一種思想方法。將所給問題的過程,按時間或空間特徵分解成若干相互聯絡的階段,以便按次序去求每階段的解 各階段開始時的...

選課 樹形動態規劃

題目大意 在大學裡每個學生,為了達到一定的學分,必須從很多課程裡選擇一些課程來學習,在課程裡有些課程必須在某些課程之前學習,如高等數學總是在其它課程之前學習。現在有n門功課,每門課有個學分,每門課有一門或沒有直接先修課 若課程a是課程b的先修課即只有學完了課程a,才能學習課程b 乙個學生要從這些課程...