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];
}

原文地址:https://www.cnblogs.com/Lis-/p/11443415.html

时间: 2024-11-06 22:22:56

HihoCoder 1055 刷油漆 (树上背包)的相关文章

hihoCoder #1055 : 刷油漆 [ 树形dp ]

传送门 结果:Accepted     提交时间:2015-05-11 10:36:08 #1055 : 刷油漆 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到,小Ho有着一棵灰常好玩的树玩具!这棵树玩具是由N个小球和N-1根木棍拼凑而成,这N个小球都被小Ho标上了不同的数字,并且这些数字都是处于1..N的范围之内,每根木棍都连接着两个不同的小球,并且保证任意两个小球间都不存在两条不同的路径可以互相到达.没错,这次说的还是这棵树玩具的故事! 小Ho的树玩具

HihoCoder 1055 : 刷油漆 树形DP第一题

刷油漆 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到,小Ho有着一棵灰常好玩的树玩具!这棵树玩具是由N个小球和N-1根木棍拼凑而成,这N个小球都被小Ho标上了不同的数字,并且这些数字都是处于1..N的范围之内,每根木棍都连接着两个不同的小球,并且保证任意两个小球间都不存在两条不同的路径可以互相到达.没错,这次说的还是这棵树玩具的故事! 小Ho的树玩具的质量似乎不是很好,短短玩了几个星期,便掉漆了! "简直是一场噩梦!"小Ho拿着树玩具眼含热泪道

hihoCoder#1055 : 刷油漆 (树形DP+01背包)

题目大意:给一棵带点权的树,现在要从根节点开始选出m个连通的节点,使总权值最大. 题目分析:定义状态dp(u,m)表示在以u为根的子树从根节点开始选出m个点连通的最大总权值,则dp(u,m)=max(dp(u,m),dp(u,m-k)+dp(son,k)),其中0<=k<m.这是01背包,k应该从大往小枚举. 代码如下: # include<iostream> # include<cstdio> # include<cmath> # include<v

hihoCoder#1055 刷油漆

原题地址 第一次做树的动归题,如果没有提示的话还是挺难的 提示里的递推式隐含了状态压缩(m从大往小遍历),不是那么好想,只能说不能再屌了. 代码: 1 #include <iostream> 2 #include <cstring> 3 4 using namespace std; 5 6 #define SIZE 128 7 8 int tree[SIZE][SIZE]; 9 int v[SIZE]; 10 int f[SIZE][SIZE]; 11 int N, M; 12 1

hihoCoder hiho一下 第十二周 #1055 : 刷油漆 (树上DP)

思路:树上的动态规划.只能刷部分节点数m,总节点数n.如果m>=n那么就可以全刷了,那就不用任何算法了.如果m<n那么就要有取舍了.用DP思路,记录下每个节点如果获得到1~m个选择所能获得的最大权值.这里的树不仅仅是二叉,可能是多叉.所以一个节点怎么合理分配给每个孩子的空间大小很关键,当第一个孩子获得了1空间,那么后面的孩子所能获得的空间就要少一个了.这样穷举每个孩子能得到的空间,来求当前节点的最大权值,会有很多种可能,m!.不用这么做. 递归步骤: 假设状态记录为 dp[节点][该节点所获得

hihocodr1055 刷油漆 树上的背包

题目链接: hihocoder1055 题解思路: 这道题要用到动态规划中的背包 可以把   涂漆节点的个数  理解为背包容量 ,则每个节点的重量为1 dp[a][b]   表示包含a(根节点)的共b个节点的最大权值 然后通过后序遍历从下往上先求得子节点的最大权值,依次向上背包 最后得到的dp[1][v]则为答案 #include<iostream> #include<cstdio> #include<cstring> #include<vector> #d

hiho #1055 : 刷油漆

上回说到,小Ho有着一棵灰常好玩的树玩具!这棵树玩具是由N个小球和N-1根木棍拼凑而成,这N个小球都被小Ho标上了不同的数字,并且这些数字都是处于1..N的范围之内,每根木棍都连接着两个不同的小球,并且保证任意两个小球间都不存在两条不同的路径可以互相到达.没错,这次说的还是这棵树玩具的故事! 小Ho的树玩具的质量似乎不是很好,短短玩了几个星期,便掉漆了! “简直是一场噩梦!”小Ho拿着树玩具眼含热泪道. “这有什么好忧伤的,自己买点油漆刷一刷不就行了?”小Hi表示不能理解. “还可以这样?”小H

hiho 1055 刷油漆 树形dp

一个简单的树上的背包问题. 代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath> 6 #include <algorithm> 7 #include <string> 8 #include <queue> 9 #include <stack>

刷油漆

刷油漆 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到,小Ho有着一棵灰常好玩的树玩具!这棵树玩具是由N个小球和N-1根木棍拼凑而成,这N个小球都被小Ho标上了不同的数字,并且这些数字都是处于1..N的范围之内,每根木棍都连接着两个不同的小球,并且保证任意两个小球间都不存在两条不同的路径可以互相到达.没错,这次说的还是这棵树玩具的故事! 小Ho的树玩具的质量似乎不是很好,短短玩了几个星期,便掉漆了! “简直是一场噩梦!”小Ho拿着树玩具眼含热泪道. “这有