樹形動態規劃

2021-06-16 15:03:18 字數 2359 閱讀 6715

分類: 演算法

2012-07-01 21:53

494人閱讀收藏 

舉報tree

output

input

struct演算法

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個節點了。

[cpp]view plain

copy

#include

#include

#include

using

namespace

std;  

struct

node  

tree[220];  

intbool

vis[110];  

intn,q;  

void

make_tree(

introot)

//一旦涉及到樹的操作,遞迴總是會簡化很多**

}  inttree_dp(

intt,

intk)  

f[t][k]=0;  

for(

inti=0;i<=k-1;i++)  

f[t][k]+=tree[t].s;  

return

f[t][k];  

}  int

main()  

memset(tree,0,sizeof

(tree));  

memset(vis,false

,sizeof

(vis));  

make_tree(1);  

memset(f,-1,sizeof

(f));  

intans=tree_dp(1,q);  

printf("%d\n"

,ans);  

return

0;  

}  

在建樹的時候也可以和圖演算法類似:

[cpp]view plain

copy

#include 

#include 

using

namespace

std;  

const

intmaxn=110;  

intn, q;  

intu, v, w;  

intdp[maxn][maxn];  

struct

node  

;  vectoradj[maxn];  

void

init( )  

}  void

dfs(

introot, 

intfather, 

intleft)  

}  }  }  

if(left==1) 

return

;  }  

intmain( )  

return

0;  

}  

樹形動態規劃

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

樹形動態規劃

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

選課 樹形動態規劃

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