[hihocoder1055]刷油漆
来源:互联网 发布:淘宝客qq群怎么加人 编辑:程序博客网 时间:2024/04/28 15:30
问题描述
给树中每个节点赋予一个value,求包含指定节点的最多还有M个节点的一个联通的最大值。
具体参考hihocoder官网。
算法详解
1. 算法框架
子问题为求以该节点为根节点的子树中最多含有0-m个节点能够得到的最大值,递归实现的算法,每个节点内部利用动态规划求解。
递归基:如果没有子节点,那么max_value[0] = 0; max_value[1] = Node.value
每个节点内部:先求每个子节点的子问题的解,然后利用所有子节点的解求解本节点,其中利用了动态规划。
2. 动态规划求解子问题
通过对于每个子节点的子问题求解,可以得到以每个子节点为根节点的子树中最多含有0-m-1个节点且联通的最大值。
把每个子节点看做一个物品,对于物品i(i大于等于0,小于子节点数),如果花j块钱(j大于等于0,小于m),可以得到v_ij的价值;求如果总共有m块钱,如何购买,可以得到最大的价值。上诉问题是个典型的背包问题,对于物品进行枚举,每件物品枚举所花钱数,即可求解。对于所有节点的总时间复杂度为O(N*M*M)~10^6.
void cal_value(int M) {// cout << num << endl; max_value[0] = 0; max_value[1] = value; int len = next.size(); if (len == 0) return; for (list<Node*>::iterator iter = next.begin();iter != next.end();++iter) (*iter)->cal_value(M-1); int values[101] = {0},tmp_max = 0; for (list<Node*>::iterator iter = next.begin();iter != next.end();++iter){ for (int m = M-1;m > 0;--m){ tmp_max = values[m]; for (int i = m;i > 0;--i){ if (values[m-i]+(*iter)->max_value[i] > tmp_max) tmp_max = values[m-i]+(*iter)->max_value[i]; } values[m] = tmp_max; } } for (int i = M;i > 1;--i) max_value[i] = values[i-1]+value; }
3. 构建树
这部分是用于去除子节点到父节点的边。
void build_tree() { list<Node*>::iterator iter; for (iter = next.begin();iter != next.end();++iter) { (*iter)->next.remove(this); (*iter)->parent = this; (*iter)->build_tree(); } }
全部代码
#include <iostream>#include <list>using namespace std;struct Node{ static int cnt; int num,value,max_value[101]; list<Node*> next; Node* parent; Node():num(cnt++),value(-1),parent(NULL) {} Node (const Node &n):num(n.num),value(n.value),next(n.next),parent(n.parent) {} ~Node() {} void build_tree() { list<Node*>::iterator iter; for (iter = next.begin();iter != next.end();++iter) { (*iter)->next.remove(this); (*iter)->parent = this; (*iter)->build_tree(); } } void cal_value(int M) {// cout << num << endl; max_value[0] = 0; max_value[1] = value; int len = next.size(); if (len == 0) return; for (list<Node*>::iterator iter = next.begin();iter != next.end();++iter) (*iter)->cal_value(M-1); int values[101] = {0},tmp_max = 0; for (list<Node*>::iterator iter = next.begin();iter != next.end();++iter){ for (int m = M-1;m > 0;--m){ tmp_max = values[m]; for (int i = m;i > 0;--i){ if (values[m-i]+(*iter)->max_value[i] > tmp_max) tmp_max = values[m-i]+(*iter)->max_value[i]; } values[m] = tmp_max; } } for (int i = M;i > 1;--i) max_value[i] = values[i-1]+value; }};int Node::cnt = 1;Node nodes[101];int main(){ int N,M; int A,B; cin >> N >> M; for (int i = 0;i < N;++i) cin >> nodes[i].value; for (int i = 1;i < N;++i) { cin >> A >> B; nodes[A-1].next.push_back(nodes+B-1); nodes[B-1].next.push_back(nodes+A-1); } nodes[0].build_tree(); nodes[0].cal_value(M); cout << nodes[0].max_value[M] << endl; return 0;}
0 0
- [hihocoder1055]刷油漆
- hihoCoder1055.刷油漆——树形Dp+01背包
- 刷油漆
- 格子刷油漆
- 蓝桥杯 格子刷油漆
- 蓝桥杯 格子刷油漆
- hihoCoder 1055 刷油漆
- 格子刷油漆
- 蓝桥杯 格子刷油漆
- hiho#1055 : 刷油漆
- 蓝桥杯 格子刷油漆
- 蓝桥网 格子刷油漆
- 格子刷油漆
- 格子刷油漆
- #1055 : 刷油漆
- 格子刷油漆
- hihocoder:#1055 : 刷油漆
- 历届试题 格子刷油漆
- Android中Bitmap,byte[],Drawable相互转化
- java常用集合类详解(有例子,集合类糊涂的来看!)
- 《Android群英传》---读书笔记8
- web项目中各种路径的获取
- 取球游戏
- [hihocoder1055]刷油漆
- 精通 CSS+DIV 网页样式与布局 118
- 异常处理
- HEVC码率控制
- AOJ.720 丢失的学妹
- 精通 CSS+DIV 网页样式与布局 119
- 七步精通Python机器学习
- 精通 CSS+DIV 网页样式与布局 120
- POJ 3685 Matrix 已翻译