时间限制: 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,表示使得涂漆结点的评分之和最高可能是多少。

样例输入

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

这道题其实不难,数上的动归,刚开始我以为我能做出来,结果状态转移方程搞错了。

先看看hihocoder上的分析吧

“是啊,我该怎么做呢?”小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信心满满的答道。

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

状态转移方程就是f(t,m) = max(f(t,m),f(t,m - m_child) + f(t_child,m_child));

感觉和完全背包有点类似。

#include<bits/stdc++.h>
using namespace std;
int m,n,v[101];
int dp[101][101] = {0};
vector<int> v1[101];
int dfs(int num,int j)
{int length = v1[num].size();if(!length){dp[num][j] = v[num];return v[num];}if(dp[num][j])return dp[num][j];dp[num][1] = v[num];for(int i = 0;i < length;++i)for(int M = m;M >= 2;--M)for(int t = M - 1;t > 0;--t){dp[num][M] = max(dp[num][M],dfs(v1[num][i],M - t) + dp[num][t]);}return dp[num][j];
}
int main()
{cin >> n >> m;for(int i = 1;i <= n;++i)cin >> v[i];for(int i = 0;i < n - 1;++i){int temp1,temp2;cin >> temp1 >> temp2;v1[temp1].push_back(temp2);}int ans = INT_MIN;ans = max(ans,dfs(1,m));cout << ans;return 0;
}

#1055 : 刷油漆相关推荐

  1. hihocoder #1055 : 刷油漆(树形dp)

    当一个节点被选择后,它的所有祖先节点也要被选择 该条件换一个说法,可以解释为:只有当选择了一个节点后,我们才可以选择它的子节点. 我们首先建立状态f[i][k],f[i][k]表示以i节点为根的子树, ...

  2. Java刷漆问题代码_Java实现蓝桥杯历届试题格子刷油漆

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

  3. nyoj 980 格子刷油漆

    格子刷油漆 时间限制: 1000 ms  |  内存限制: 65535 KB 难度: 3 描述 X国的一段古城墙的顶端可以看成 2*N个格子组成的矩形(如下图所示),现需要把这些格子刷上保护漆. 你可 ...

  4. 【蓝桥杯】历届试题 格子刷油漆(动态规划)

    历届试题 格子刷油漆 问题描述 X国的一段古城墙的顶端可以看成 2×N个格子组成的矩形(如下图所示),现需要把这些格子刷上保护漆. 例如下图是一个长度为3,高为2的城墙 你可以从任意一个格子刷起,刷完 ...

  5. 历届试题 格子刷油漆

    历届试题 格子刷油漆   问题描述 X国的一段古城墙的顶端可以看成 2*N个格子组成的矩形(如下图所示),现需要把这些格子刷上保护漆. 你可以从任意一个格子刷起,刷完一格,可以移动到和它相邻的格子(对 ...

  6. 蓝桥 历届试题 格子刷油漆

    历届试题 格子刷油漆 时间限制:1.0s   内存限制:256.0MB 问题描述 X国的一段古城墙的顶端可以看成 2*N个格子组成的矩形(如下图所示),现需要把这些格子刷上保护漆. 你可以从任意一个格 ...

  7. 蓝桥杯 PREV-15 格子刷油漆

    历年试题 PREV-15 格子刷油漆 题目:传送门 解析: 分析题目我们可以知道刷油漆的的起点可以分为两类,一是在第一列和最后一列的四个格子开始:而是在中间的某个格子开始. 对于从角落开始的方案比较好 ...

  8. [蓝桥杯]各自刷油漆Python3满分解法

    [蓝桥杯]各自刷油漆Python3满分解法 文章目录 [蓝桥杯]各自刷油漆Python3满分解法 前言 一.动态规划算法 二.本题思路 1.观察解的特征 2.设计递归方程 3.注意边界特殊情况 三.代 ...

  9. XJOI 3404 刷油漆 题解

    时间:1s 空间:128M 题目描述: 从1到n有n块砖需要刷油漆,砖的编号被a整除的要被刷成红色,被b整除的被刷成蓝色,同时被a,b整除的既可以被刷成红色,也可以被刷成蓝色.等你刷完后,对于每块红色 ...

最新文章

  1. 程序员面试时,不小心说了真话…...
  2. ps grep java_ps -ef | grep java 查看所有关于java的进程
  3. java s0 s1_Java GC 变量含义(S0 S1 E O P YGC YGCT FGC FGCT GCT)详解
  4. c++二叉树编程实践
  5. GitHub之深入解析如何对项目做出贡献
  6. selenium操作chrome时的一些配置
  7. 用vue实现模态框组件
  8. 【TensorFlow-windows】(二) 实现一个去噪自编码器
  9. c语言编写自由落体运动程序,3个C语言程序急求大神编写,再次先谢过了、
  10. xcopy使用与案例使用
  11. spring-boot-maven-plugin 爆红,分析原因并解决。
  12. unity 序列帧动画 UGUI GPU版
  13. python怎么生成图_python 生成图表
  14. 蓝桥杯——2015年C++A组第3题:奇妙的数字【枚举】
  15. ImDisk 命令行用法
  16. 神经网络模型应用实例SPSS - 典型的神经网络模型 - 神经网络模型的应用
  17. 如何利用Swagger生成统一格式的Responses
  18. Greenplum小把戏 - ip地址表达方式转换函数
  19. VMware View中智能卡和证书身份验证
  20. 《七哥说道》第十章:今天我,寒夜里看雪飘过

热门文章

  1. 摊上事了! Facebook向用户手机发生日信息涉嫌违法
  2. 中继器的使用方法~~
  3. 饥荒如何解锁机器人_饥荒联机机器人怎么玩 饥荒联机机器人玩法攻略(图文)...
  4. EXCEL计算汉字的GBK码和UNICOD的自定义函数
  5. 智能驾驶新一轮芯片争夺战开启
  6. Spring系列学习之Spring Data R2DBC数据访问
  7. python将模块转变成whl文件
  8. BI 系统中为什么会有很多冗余的快照表?
  9. lubuntu 中文输入法安装
  10. c语言的子程序文件名,Adams2012编译C语言用户子程序