樹型dp Zoj3201 tree of tree

來源:互聯網
上載者:User

 
^_^ o(∩∩)o...我去剛要打個哈哈出現這麼多顏文字還那麼醜

這題 算是 樹型dp經典的 小變種 了吧 。。

首先 理解一下 啥叫 樹型dp,
樹型樹型,告訴我們 這是一個 基於樹(二叉樹)結構的dp

那麼自然要有建樹的過程。
建樹 有 三種  1)單方向 2)鄰接表  3)孩子兄弟

再想到dp是自下ershang
故而先計算孩子節點資訊
利用孩子節點資訊算出根節點資訊

寫出狀態轉移方程

通常分為 葉子節點:dp[][]
                非葉子節點: dp[i][]= blablabla

這道題的狀態轉移方程

考慮每個節點 i為根 的sizeK的子樹的最大 weight;
    dp[i][sizeK]=max(dp[i][sizeK] , dp[i的孩子][sizeK-k]+dp[i][k]);  (  sizeK= K ~ 1, k=sizeK~1);

最後  掃一遍 dp[i][題目指定子樹大小];

ok.

#include <iostream>#include <string.h>#include <vector>#define Max(a,b) (a)>(b)?(a):(b)using namespace std;const int maxn=110;int f[maxn][maxn],N,K,w[maxn];bool vis[maxn];vector<int> node[maxn];void dfs(int r){int size=node[r].size(),i,j,t;f[r][0]=0;f[r][1]=w[r];for(i = 0;i < size; i++){j=node[r][i];dfs(j);for(j = K;j >= 1; j--){for (t = j; t>=1; t--) {f[r][j]=Max(f[r][j],f[r][t]+f[j][j-t]);}}}}int main(void){while(cin>>N>>K){int i;for (i = 0; i < N ; i++) {cin>>w[i];node[i].clear();}int a,b;memset(vis,0,sizeof(vis));memset(w,0,sizeof(w));for (i = 1; i < N; i++) {cin>>a>>b;node[a].push_back(b);vis[b]=true;}for(i = 0;i < N && vis[i] ;i++);dfs(i);int ans=0;for (i = 0; i < N; i++) {if(f[i][K]>ans) ans=f[i][K];}cout<<ans<<endl;}return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.