hihocodr1055 刷油漆 树上的背包

题目链接:

hihocoder1055

题解思路:

这道题要用到动态规划中的背包

可以把   涂漆节点的个数  理解为背包容量 ,则每个节点的重量为1

dp[a][b]   表示包含a(根节点)的共b个节点的最大权值

然后通过后序遍历从下往上先求得子节点的最大权值,依次向上背包

最后得到的dp[1][v]则为答案

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#define MAXN 105
using namespace std;
vector<int>q[MAXN];   //
int dp[MAXN][MAXN];
int n,v;
int max(int a,int b)
{
    return a>b?a:b;
}
void dfs_package(int loc)
{
    for(int i=0;i<q[loc].size();i++)
        dfs_package(q[loc][i]);

    dp[loc][0]=0;

    for(int i=0;i<q[loc].size();i++)
        for(int j=v;j>=2;j--)             //j只能到2  因为必须要保证dp[x][1]不被改变(包含根节点)
            for(int k=1;k<j;k++)           //取第i棵子书的k个节点
                dp[loc][j]=max(dp[loc][j],dp[loc][j-k]+dp[q[loc][i]][k]);
}
int main()
{
    scanf("%d%d",&n,&v);
    for(int i=1;i<=n;i++)
        scanf("%d",&dp[i][1]);
    int a,b;
    for(int i=1;i<n;i++)
    {
        scanf("%d%d",&a,&b);
        if(a<b)
            q[a].push_back(b);
        else
            q[b].push_back(a);
    }
    dfs_package(1);
    cout<<dp[1][v]<<endl;
    return 0;
}
时间: 2024-10-12 23:22:46

hihocodr1055 刷油漆 树上的背包的相关文章

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

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

刷油漆

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

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

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

poj1155 树上的背包

题目链接:http://poj.org/problem?id=1155 题意:给定一棵树,1为根结点表示电视台,有m个叶子节点表示客户,有n-m-1个中间节点表示中转站,每条树边有权值.现在要在电视台播放一场比赛,每个客户愿意花费cost[i]的钱观看,而从电视台到每个客户也都有个费用,并且经过一条边只会产生一个费用.问电视台不亏损的情况最多有几个客户可以看到比赛? 思路:在树上的背包,具体看代码注释. 代码: #include<iostream> #include<cstdio>

hiho_1055_刷油漆

题目大意 一棵树,每个节点都有相应的value值.从根开始选择M个节点相互连通,使得这些节点的value值之和最大. 题目链接:[刷油漆][1] 题目分析 典型的树形dp,dp[i][j] 表示以节点i为根的子树中选择j个节点(从i节点出发)相互连通,所能达到的节点value之和的最大值.可以很容易知道, dp[root][k] = max{dp[ch1][k1] + dp[ch2][k2] + .. dp[cht][kt]}. 即将k-1个节点分配给 根节点root的t个子节点,其中 k1 +

格子刷油漆

题目:格子刷油漆 链接:http://lx.lanqiao.org/problem.page?gpid=T38 题意:要遍历2行n列的格子,一次只能遍历四周,遍历过就不能再遍历,问有多少种遍历方法(起点也任意,只要能遍历完所有格子就可以) 题目思路: 分两大块: 1.从某一个角落出发:A[n] 比如从A点出发,因为要遍历所有的格子,所以要想遍历同一列的D,就只有三种方法: 1. 直接到D,然后再遍历BCEF这块,那么这种情况的数量就是2*A[n-1],因为B.E你可以选一个开始,所以乘2. 2.

算法笔记_185:历届试题 格子刷油漆(Java)

目录 1 问题描述 2 解决方案   1 问题描述 问题描述 X国的一段古城墙的顶端可以看成 2*N个格子组成的矩形(如下图所示),现需要把这些格子刷上保护漆. 你可以从任意一个格子刷起,刷完一格,可以移动到和它相邻的格子(对角相邻也算数),但不能移动到较远的格子(因为油漆未干不能踩!) 比如:a d b c e f 就是合格的刷漆顺序. c e f d a b 是另一种合适的方案. 当已知 N 时,求总的方案数.当N较大时,结果会迅速增大,请把结果对 1000000007 (十亿零七) 取模.

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

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

分组背包及树上分组背包

分组背包是说有n组物品 每个组别只能选一个 体积限制V 的最大价值w 二维: //f[i][j] 表示 前i组体积为j的最大价值 for(int i=1;i<=N;i++) //组别 for(int k=1;k<=n[i];k++) //每个物品 for(int j=V;j>=0;j--) //体积 f[i][j]=max(f[i][j],f[i-1][j-v[i][k]]+w[i][k]); 一维: //f[i]表示重量为i时的最大价值 for(int i=1;i<=n;i++)