zoukankan      html  css  js  c++  java
  • Ural-1018 Binary Apple Tree(树形dp+分组背包)

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    using namespace std;
    
    const int maxn = 100;
    int dp[maxn][maxn]; //dp[i][j]表示以i为根,保留j个点的最大权值。
    int N,Q;
    int G[maxn][maxn];
    int num[maxn];   //以i为根的树的节点个数。
    
    //这里处理的时候要注意可以把边的权值压倒儿子节点。
    void dfs(int u,int fa){
        num[u] = 1;
        for(int v=1;v<=N;v++){
            if(!G[u][v] || v == fa)  continue;
    
            dfs(v,u);
            num[u] += num[v];
        }
    
        for(int v=1;v<=N;v++){    //相当于分组k。
            if(!G[u][v] || v == fa)  continue;
    
            for(int i=num[u];i>0;i--){     //相对于下面的V -> 0
                for(int j=1;j<i&&j<=num[v];j++)    //枚举组k中的元素。
                    dp[u][i] = max(dp[u][i],dp[u][i-j]+dp[v][j]+G[u][v]);
            }
        }
    }
    /**  
    f[k][v]表示前k组物品花费费用v能取得的最大权值
    f[k][v]=max{f[k-1][v],f[k-1][v-c[i]]+w[i]|物品i属于组k}
    分组背包一维数组的伪代码:
    for 所有的组k
        for v=V..0
            for 所有的i属于组k
                f[v]=max{f[v],f[v-c[i]]+w[i]}
    **/
    int main()
    {
        cin>>N>>Q;
        memset(G,0,sizeof(G));
        memset(dp,0,sizeof(dp));
        for(int i=1;i<N;i++){
            int u,v,w;
            scanf("%d %d %d",&u,&v,&w);
            G[u][v] = G[v][u] = w;
        }
        dfs(1,-1);
        printf("%d
    ",dp[1][Q+1]);
    }
    View Code
  • 相关阅读:
    内置函数详解
    关于内置函数
    ac自动机练习 HihoCoder 1036
    字典树Trie练习 HihoCoder 1014
    HDU 6170 Two String 动态规划
    NOJ 1190 约瑟夫问题 线段树OR树状数组
    NOJ 1186 灭蚊药水
    LightOJ 1085 树状数组+动态规划
    LightOJ 1066
    LightOJ 1080 树状数组
  • 原文地址:https://www.cnblogs.com/acmdeweilai/p/3320376.html
Copyright © 2011-2022 走看看