zoukankan      html  css  js  c++  java
  • 树形DP

     给一棵节点带权的树,找到一个有k个节点的子树,求这个子树的最大权值。

    dp[u][k]表示以u为根的子树中包含u结点的大小为k的子树的最大权和

      然后对u的每个子节点做分组背包,因为对于u的每个儿子,可以选择分配
       1,2,3...k-1个节点给它

     状态转移方程:

       当节点大小为K时,可以由根节点为u,子树大小为k-t, 加上根节点为v,子树大小为t的状态转移得到(v为u的子节点),即:


       dp[u][k] = max(dp[u][k] , dp[u][k-t]+dp[v][t]);//v是u的儿子节点

    
    
    #include <iostream>  
    #include <cstdio>  
    #include <cstring>  
    #include <algorithm>  
    #include <vector>  
    using namespace std;
    //简单的树形DP
    int max(int a,int b){
        return a>b?a:b;
    }
    const int inf = 1<<30;
    int n,k;
    int x[202];
    int dp[202][202];
    vector <int> List[202];
    
    void dfs(int u,int father){
        int i,j;
        for(i=0;i<List[u].size();i++)
        {
            int v=List[u][i];
            if(v==father) 
                continue;
            dfs(v,u);
            
            for(j=k;j>=1;j--)//一定要倒序
            {
                for(int t=1;t<=j;t++)
                    dp[u][j]=max(dp[u][j] , dp[u][t]+dp[v][j-t]);
            }
        }
    }
    int main(){
        scanf("%d %d",&n,&k);
        int i,j,a,b;
        for(i = 0;i <= n;i++) //清空list表
            List[i].clear();
        memset(dp,0,sizeof(dp));
        dp[0][1]=0;//以0为根节点有且只有1个节点字数的最大权重
        for(i=1;i<=n;i++){    
            scanf("%d %d",&b,&dp[i][1]);//以i为根节点有且只有1个节点字数的最大权重
            List[i].push_back(b);
            List[b].push_back(i);
        }
        k++;//多加一个0节点
        dfs(0,-1);
        printf("%d
    ",dp[0][k]);//以0为根节点有且只有m个节点字数的最大权重
        return 0;
    }
  • 相关阅读:
    ECharts之类型bar(堆积条形图)
    ECharts之类型bar
    ECharts之类型pie
    ECharts入门一
    ECharts第一个实例
    html树形菜单控件
    【JavaScript】Javascript中document.execCommand()的用法
    【JavaScript】dhtmlXTree 中文API
    【javascript】addEventListener事件方法
    java判断集合是否重复的一种便捷方法
  • 原文地址:https://www.cnblogs.com/zeze/p/6012918.html
Copyright © 2011-2022 走看看