[hihoCoder] #1055 : 刷油漆
描述
上回说到,小Ho有着一棵灰常好玩的树玩具!这棵树玩具是由N个小球和N-1根木棍拼凑而成,这N个小球都被小Ho标上了不同的数字,并且这些数字都是处于1..N的范围之内,每根木棍都连接着两个不同的小球,并且保证任意两个小球间都不存在两条不同的路径可以互相到达。没错,这次说的还是这棵树玩具的故事!
小Ho的树玩具的质量似乎不是很好,短短玩了几个星期,便掉漆了!
“简直是一场噩梦!”小Ho拿着树玩具眼含热泪道。
“这有什么好忧伤的,自己买点油漆刷一刷不就行了?”小Hi表示不能理解。
“还可以这样?”小Ho顿时兴高采烈了起来,立马跑出去买回来了油漆,但是小Ho身上的钱却不够——于是他只买回了有限的油漆,这些油漆最多能给M个结点涂上颜色,这就意味着小Ho不能够将他心爱的树玩具中的每一个结点都涂上油漆!
小Ho低头思索了半天——他既不想只选一部分结点补漆,也不想找小Hi借钱,但是很快,他想出了一个非常棒的主意:将包含1号结点的一部分连通的结点进行涂漆(这里的连通指的是这一些涂漆的结点可以互相到达并且不会经过没有涂漆的结点),然后将剩下的结点拆掉!
那么究竟选择哪些结点进行涂漆呢?小Ho想了想给每个结点都评上了分——他希望最后留下来,也就是涂漆了的那些结点的评分之和可以尽可能的高!
那么,小Ho该如何做呢?
输入
每个测试点(输入文件)有且仅有一组测试数据。
每组测试数据的第一行为两个整数N、M,意义如前文所述。
每组测试数据的第二行为N个整数,其中第i个整数Vi表示标号为i的结点的评分
每组测试数据的第3~N+1行,每行分别描述一根木棍,其中第i+1行为两个整数Ai,Bi,表示第i根木棍连接的两个小球的编号。
对于100%的数据,满足N<=10^2,1<=Ai<=N, 1<=Bi<=N, 1<=Vi<=10^3, 1<=M<=N
小Hi的Tip:那些用数组存储树边的记得要开两倍大小哦!
输出
对于每组测试数据,输出一个整数Ans,表示使得涂漆结点的评分之和最高可能是多少。
- 样例输入
-
10 4
370 328 750 930 604 732 159 167 945 210
1 2
2 3
1 4
1 5
4 6
4 7
4 8
6 9
5 10 - 样例输出
-
2977
“是啊,我该怎么做呢?”小Ho想道,但是如果能很快就自己想出来那也就不是小Ho了,于是小Ho还是老老实实去请教了小Hi。
小Hi听了小Ho的问题,道:“这个问题不是很简单么?来,我们再重复一下之前的步骤——先抽象你的问题。”
“好的!应该是这样的——f(t, m)表示,在以t为根的一棵树中,选出包含根节点t的m个连通的结点,能够获得的最高的评分,然后我们的答案就是f(1, M)!”身经百战的小Ho也是只需要一下点拨,立马就答了出来。
“那么你应该如何分解这个问题为子问题呢?”小Hi继续问道。
“一般的思路会是这样子的,首先我要包含根节点,然后与根节点连通的结点最开始便是根节点的子结点,而所有选择的结点都要互相连通的话,那么如果选择某一棵子树中的结点的话就势必也需要选择这棵子树的根节点——所以就变成了一个规模小一些的子问题。比如在求解f(t, m)的时候,我先枚举t的第一个子结点t1中选出的结点数m1,然后枚举t的第二个子结点t2中选出的结点数m2……一直到t的最后一个子结点tk中选出的结点数mk,这样就有f(t, m) = max{f(t1, m1) + f(t2, m2) + …… + f(tk, mk)} + v(t),并且需要保证m1+m2+...+mk+1=m。”小Ho答道。
小Hi摇了摇头:“但是你不觉得这样这个算法就是指数级了么?m1...mk可能有的方案数可是非常多的呢!”
“唔……我知道了,这里不是和无限背包问题很像么?我可以不用单独的求解每一个f(t, m)而是针对于每一个t,同时求解它的f(t, 0..M),这样的话,我就可以把m视作背包容量,把每个子结点t_child都视作一件单位重量为1的物品,但是和背包问题不同的是,这件物品的总价值并不是单位价值乘以总重量,而是重量为m_child的该物品的价值为f(t_child, m_child),这样我就可以像无限背包问题一样,用这样的方法来进行求解!
“没错呢!但是你这样的话不会导致f(t_child, m_child)计算很多次么?”小Hi也是故意要考一考小Ho。
“这你就小瞧我了,我学了这么久动态规划难道还不知道我可以以后序遍历的方式访问这棵树,这样当计算f(t, 0..M)的时候,我就已经计算出了所有的f(t_child, m_child)的值,如果我将这些值储存在数组中的话,我就不需要再递归计算了!”小Ho信心满满的答道。
“真聪明!那你还不快去写程序?你的油漆都要干了哦!”
#include <bits/stdc++.h>
using namespace std; int N, M;
vector<int> v;
vector<vector<int>> graph;
vector<vector<int>> dp;
int a, b; void dfs(int u, int p) {
dp[u][] = v[u];
for (auto v : graph[u]) if (v != p) {
dfs(v, u);
for (int i = M; i >= ; --i) {
for (int j = ; j < i; ++j) {
dp[u][i] = max(dp[u][i], dp[u][i-j] + dp[v][j]);
}
}
}
} void solve() {
dfs(, );
cout << dp[][M] << endl;
} int main() {
while (cin >> N >> M) {
v.assign(N + , );
graph.assign(N + , vector<int>());
dp.assign(N + , vector<int>(M + , ));
for (int i = ; i <= N; ++i) {
cin >> v[i];
}
for (int i = ; i < N - ; ++i) {
cin >> a >> b;
graph[a].push_back(b);
graph[b].push_back(a);
}
solve();
}
return ;
}
[hihoCoder] #1055 : 刷油漆的更多相关文章
- hihoCoder #1055 : 刷油漆 [ 树形dp ]
传送门 结果:Accepted 提交时间:2015-05-11 10:36:08 #1055 : 刷油漆 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到 ...
- HihoCoder 1055 : 刷油漆 树形DP第一题(对象 点)
刷油漆 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到,小Ho有着一棵灰常好玩的树玩具!这棵树玩具是由N个小球和N-1根木棍拼凑而成,这N个小球都被小Ho标上了 ...
- hihoCoder#1055 : 刷油漆 (树形DP+01背包)
题目大意:给一棵带点权的树,现在要从根节点开始选出m个连通的节点,使总权值最大. 题目分析:定义状态dp(u,m)表示在以u为根的子树从根节点开始选出m个点连通的最大总权值,则dp(u,m)=max( ...
- HihoCoder 1055 刷油漆 (树上背包)
题目:https://vjudge.net/contest/323605#problem/A 题意:一棵树,让你选择m个点的一个连通块,使得得到的权值最大 思路:树上背包,我们用一个dp数组,dp[i ...
- hihoCoder hiho一下 第十二周 #1055 : 刷油漆 (树上DP)
思路: 只能刷部分节点数m,总节点数n.如果m>=n那么就可以全刷了,那就不用任何算法了.如果m<n那么就要有取舍了.用DP思路,记录下每个节点如果获得到1~m个选择所能获得的最大权值.这 ...
- hiho #1055 : 刷油漆
上回说到,小Ho有着一棵灰常好玩的树玩具!这棵树玩具是由N个小球和N-1根木棍拼凑而成,这N个小球都被小Ho标上了不同的数字,并且这些数字都是处于1..N的范围之内,每根木棍都连接着两个不同的小球,并 ...
- hihoCoder week12 刷油漆
题目链接: https://hihocoder.com/contest/hiho12/problem/1 给出一棵树 每个节点的价值 求以1为根的树中,选取m个相联通的节点的最大价值和 #includ ...
- hiho 1055 刷油漆 树形dp
一个简单的树上的背包问题. 代码: #include <iostream> #include <cstdio> #include <cstring> #includ ...
- HihoCoder第十二周:刷油漆
#1055 : 刷油漆 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到,小Ho有着一棵灰常好玩的树玩具!这棵树玩具是由N个小球和N-1根木棍拼凑而成,这N个小球 ...
随机推荐
- [jQuery] $.map, $.each, detach() , $.getJSOIN()
$.map function will return the modifies array. $.each function will not new a new array, the old val ...
- 一款纯css实现的垂直时间线效果
今天给大家分享一款纯css实现的垂直时间线效果.垂直时间线适合放在类似任务时间安排的网页上.该实现采用了蓝色作为主题色,界面效果还不错.一起看下效果图: 实现的代码. html代码: ... 阅读原文 ...
- 修改字段结构之GP工具
即然有这个需求,就有人这样做.有人写了GP工具直接来重命名字段名和字段别名.工具及源码下载链接为:http://www.t00y.com/file/90123888 加载到ToolBox中后,可直接运 ...
- 解决Synergy的鼠标无法从服务器(server)机屏幕移动到客户机(client)屏幕的问题
我在工作时使用一台Win 7笔记本和一台Ubuntu台式机,为了提升工作效率,我使用Synergy在两台机器间共享了笔记本的鼠标和键盘,即笔记本作为服务器,台式机作为客户机. 这样使用了大概一年多,但 ...
- 4667 Building Fence 解题报告
题意:给n个圆和m个三角形,且保证互不相交,用一个篱笆把他们围起来,求最短的周长是多少. 解法1:在每个圆上均匀的取2000个点,求凸包周长就可以水过. 解法2:求出所有圆之间的外公切线的切点,以及过 ...
- python解析发往本机的数据包示例 (解析数据包)
tcp.py # -*- coding: cp936 -*- import socket from struct import * from time import ctime,sleep from ...
- sql面试-查询选修课程的学生
首先: 1 . EXISTS 子查询找到的提交 NOT EXISTS 子查询中 找不到的提交 说明:不要去翻译为存在和不存在,把脑袋搞晕. 2 . 建立程序循环的概念,这是一个动态的查询过程.如 F ...
- 36个Android开发常用代码片段
//36个Android开发常用代码片段 //拨打电话 public static void call(Context context, String phoneNumber) { context.s ...
- exeption ORA-00907: missing right parenthesis
exeption ORA-00907: missing right parenthesis CreationTime--2018年8月16日11点11分 Author:Marydon 1.情景展示 ...
- C# 关闭显示器(显示)
1.先引入DllImport所在的名称空间 using System.Runtime.InteropServices; 2.引入方法 [DllImport("user32.dll" ...
