传送门

结果:Accepted     提交时间:2015-05-11 10:36:08

#1055 : 刷油漆

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

上回说到,小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,表示使得涂漆结点的评分之和最高可能是多少。

样例输入
  1. 10 4
  2. 370 328 750 930 604 732 159 167 945 210
  3. 1 2
  4. 2 3
  5. 1 4
  6. 1 5
  7. 4 6
  8. 4 7
  9. 4 8
  10. 6 9
  11. 5 10
样例输出
  1. 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信心满满的答道。

“真聪明!那你还不快去写程序?你的油漆都要干了哦!”

1055 刷油漆 AC G++ 6ms 0MB 34秒前 查看
  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include <algorithm>
  5. #include <stack>
  6. #include <cctype>
  7. #include <vector>
  8. #include <cmath>
  9.  
  10. #define ll long long
  11.  
  12. using namespace std;
  13.  
  14. const int N = ;
  15. const int M = ;
  16. const ll mod = ;
  17.  
  18. int n,m;
  19. ll value[N];
  20. ll dp[N][N];
  21. vector<int> G[N];
  22.  
  23. void dfs(int u,int f)
  24. {
  25. int i,v,j,k;
  26. int tot,te;
  27. tot=;
  28. dp[u][]=value[u];
  29. dp[u][]=;
  30. for(i=;i<G[u].size();i++){
  31. v=G[u][i];
  32. if(v==f) continue;
  33. dfs(v,u);
  34. te=G[v].size();
  35. tot+=te;
  36. for(j=n;j>=;j--){
  37. for(k=;k<=j-;k++){
  38. if(dp[u][j-k]==- || dp[v][k]==-) continue;
  39. dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k]);
  40. }
  41. }
  42. }
  43. }
  44.  
  45. void fun()
  46. {
  47. dfs(,-);
  48. }
  49.  
  50. int main()
  51. {
  52. //freopen("data.in","r",stdin);
  53. //scanf("%d",&T);
  54. //for(int ccnt=1;ccnt<=T;ccnt++){
  55. while(scanf("%d%d",&n,&m) != EOF) {
  56. int i;
  57. memset(dp,-,sizeof(dp));
  58. for(i=;i<=n;i++){
  59. scanf("%lld",&value[i]);
  60. G[i].clear();
  61. }
  62. int a,b;
  63. for(i=;i<=n-;i++){
  64. scanf("%d%d",&a,&b);
  65. G[a].push_back(b);
  66. G[b].push_back(a);
  67. }
  68. fun();
  69. // cout<<dp[1][m]<<endl;
  70. printf("%lld\n",dp[][m]);
  71. }
  72. return ;
  73. }

hihoCoder #1055 : 刷油漆 [ 树形dp ]的更多相关文章

  1. HihoCoder 1055 : 刷油漆 树形DP第一题(对象 点)

    刷油漆 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到,小Ho有着一棵灰常好玩的树玩具!这棵树玩具是由N个小球和N-1根木棍拼凑而成,这N个小球都被小Ho标上了 ...

  2. hiho 1055 刷油漆 树形dp

    一个简单的树上的背包问题. 代码: #include <iostream> #include <cstdio> #include <cstring> #includ ...

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

    题目大意:给一棵带点权的树,现在要从根节点开始选出m个连通的节点,使总权值最大. 题目分析:定义状态dp(u,m)表示在以u为根的子树从根节点开始选出m个点连通的最大总权值,则dp(u,m)=max( ...

  4. [hihoCoder] #1055 : 刷油漆

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到,小Ho有着一棵灰常好玩的树玩具!这棵树玩具是由N个小球和N-1根木棍拼凑而成,这N个小球都被小Ho标上了不同的数 ...

  5. HihoCoder 1055 刷油漆 (树上背包)

    题目:https://vjudge.net/contest/323605#problem/A 题意:一棵树,让你选择m个点的一个连通块,使得得到的权值最大 思路:树上背包,我们用一个dp数组,dp[i ...

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

    思路: 只能刷部分节点数m,总节点数n.如果m>=n那么就可以全刷了,那就不用任何算法了.如果m<n那么就要有取舍了.用DP思路,记录下每个节点如果获得到1~m个选择所能获得的最大权值.这 ...

  7. 格子刷油漆(dp)-----------蓝桥备战系列

    标题:格子刷油漆 X国的一段古城墙的顶端可以看成 2*N个格子组成的矩形(如图1所示),现需要把这些格子刷上保护漆. 你可以从任意一个格子刷起,刷完一格,可以移动到和它相邻的格子(对角相邻也算数),但 ...

  8. hiho #1055 : 刷油漆

    上回说到,小Ho有着一棵灰常好玩的树玩具!这棵树玩具是由N个小球和N-1根木棍拼凑而成,这N个小球都被小Ho标上了不同的数字,并且这些数字都是处于1..N的范围之内,每根木棍都连接着两个不同的小球,并 ...

  9. hihoCoder week12 刷油漆

    题目链接: https://hihocoder.com/contest/hiho12/problem/1 给出一棵树 每个节点的价值 求以1为根的树中,选取m个相联通的节点的最大价值和 #includ ...

随机推荐

  1. Kotlin学习的一些心得

    1.工程manifest中的application节点有冲突时,添加 xmlns:tools="http://schemas.android.com/tools" tools:re ...

  2. .net4.5注册到iis

    开始->所有程序->附件->鼠标右键点击“命令提示符”->以管理员身份运行->%windir%\Microsoft.NET\Framework\v4.0.30319\as ...

  3. Ubuntu系统下配置PHP支持SQLServer 2005

    最近在做一个项目,该项目的数据库是微软公司的的SQLserver ,数据库安装在另一台windows服务器上,而项目却部署在ubuntu server上.那么这样就会涉及到项目在linux上如何链接S ...

  4. 50个Bootstrap扩展插件

    Bootstap这个框架本身已经包含了开发网页的众多要素,包括了常用的工具以及扩展组件,如果你在开发页面时觉得在某些方面还不够的话,不妨看看最新收集的50个Bootstrap扩展插件,这些插件在我们平 ...

  5. swift 泛型的类型约束

    总结: 1.类型约束只能添加到泛型参量上面 2.关联类型是泛型参量: 3.关联类型可以通过 协议.关联类型名称的形式引用: func allItemsMatch<C1: Container, C ...

  6. Android Studio 中文件查询方法总结

    搜索单词 Windows: Ctrl + F Mac   : Cmd + F 会在当前激活的文件上查询输入的关键字,以高亮显示 跳转行 Windows: Ctrl + L Mac   : Cmd + ...

  7. saltstack 源码安装

    面向对象编程(oop) 面向对象: 面向对象三大特性: 封装 继承 多肽封装: 封装就是将具体的客观事物封装成抽象的类.并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可行的进行信息隐藏继承 ...

  8. CodeForces - 1059D——二分/三分

    题目 题目链接 简单的说,就是作一个圆包含所有的点且与x轴相切,求圆的最小半径 方法一 分析:求最小,对半径而言肯定满足单调性,很容易想到二分.我们二分半径,然后由于固定了与X轴相切,我们对于每一个点 ...

  9. java根据freeMark模板生成内容

    根据ftl模板生成文件内容可以用来生成代码模板,如下所示: aa.ftl name : ${name} age : ${age} aa.java package mall_tools; import ...

  10. 第1节 flume:4、离线项目处理的整个架构图;5、flume的基本介绍;

    第1节 flume:4.离线项目处理的整个架构图 辅助系统工具:flume,azkaban,sqoop. 在一个完整的离线大数据处理系统中,除了hdfs+mapreduce+hive组成分析系统的核心 ...