zoukankan      html  css  js  c++  java
  • HihoCoder 1055 刷油漆 (树上背包)

    题目:https://vjudge.net/contest/323605#problem/A

    题意:一棵树,让你选择m个点的一个连通块,使得得到的权值最大

    思路:树上背包,我们用一个dp数组,dp[i][j] ,代表以i为根时的选其子树j个节点所得到的最大值,然后我们对于每个以i为根我们当做有m件物品,然后对于不同的子树当作不同的分组即可

    #include<bits/stdc++.h>
    #define maxn 105
    #define mod 1000000007
    using namespace std;
    typedef long long ll;
    int n,m;
    int dp[maxn][maxn];
    int d[maxn];
    vector<int> mp[maxn];
    void dfs(int x,int f){
        for(int i=0;i<mp[x].size();i++){
            int u=mp[x][i];
            if(u==f) continue;
            dfs(u,x);
            for(int t=m;t>=0;t--){//用当前子树得到的物品来更新当前节点的值
                for(int j=t;j>=0;j--){
                    if(t-j>=0){
                        dp[x][t]=max(dp[x][t],dp[x][t-j]+dp[u][j]);
                    }
                }
            }
        }
        if(x!=0){
            for(int t=m;t>0;t--){
                dp[x][t]=dp[x][t-1]+d[x];
            }
        }
    }
    int main(){
        scanf("%d%d",&n,&m);
        int x,y;
        for(int i=1;i<=n;i++) scanf("%d",&d[i]);
        for(int i=0;i<n-1;i++){
            scanf("%d%d",&x,&y);
            mp[x].push_back(y);
            mp[y].push_back(x);
        } 
        dfs(1,-1);
        cout<<dp[1][m];
    }
  • 相关阅读:
    洛谷
    洛谷
    洛谷
    洛谷
    模板
    .
    洛谷
    洛谷
    洛谷
    poj 2955"Brackets"(区间DP)
  • 原文地址:https://www.cnblogs.com/Lis-/p/11443415.html
Copyright © 2011-2022 走看看