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
13 void traverse(int t, int p) {
14   f[t][0] = 0;
15   f[t][1] = v[t];
16
17   for (int i = 1; i <= tree[t][0]; i++) {
18     int t_child = tree[t][i];
19     if (t_child == p)
20       continue;
21     traverse(t_child, t);
22     for (int m = M; m >= 2; m--) {
23       for (int m_child = 1; m_child <= m - 1; m_child++) {
24         f[t][m] = max(f[t][m], f[t][m - m_child] + f[t_child][m_child]);
25       }
26     }
27   }
28 }
29
30 int main() {
31   int res = 0;
32
33   memset(tree, 0, SIZE * SIZE * sizeof(int));
34   memset(f, 0, SIZE * SIZE * sizeof(int));
35
36   cin >> N >> M;
37   for (int i = 1; i <= N; i++)
38     cin >> v[i];
39   for (int i = 1; i <= N - 1; i++) {
40     int a, b;
41     cin >> a >> b;
42     tree[a][0]++;
43     tree[b][0]++;
44     tree[a][tree[a][0]] = b;
45     tree[b][tree[b][0]] = a;
46   }
47
48   traverse(1, -1);
49   cout << f[1][M] << endl;
50
51   return 0;
52 }
时间: 2024-10-06 04:13:01

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 刷油漆 (树上背包)

题目: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 namespac

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

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

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拿着树玩具眼含热泪道. “这有

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 +