hdu 1561 The more, The Better(树形dp)
2016-03-17 22:38
337 查看
The more, The Better
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1561解题思路:
依赖背包 -> 树形dp题意大意:
给你一个树形结构,问最多拿max个城堡,能获得的价值最大,拿下面时一定也要先拿上面的。
算法思想:
定义状态dp[i][j] : 当前i节点及其子树下最多选择j个城市的最大值为dp[i][j];
我们考虑到特殊状态:i节点下没有孩子那么dp[i][2,3,4,5...]均为-1(因为多选总比少选好,并且选择完后城市总是有剩余)
1. 判断当前节点P有没有孩子,如果有则令当前节点的孩子为P重复(1)操作,如果没有则到(2)操作;
2. 将当前节点P的状态更新到期父节点上,
更新操作为dp[P'father][i] = max(dp[P'father][i], dp[P'father][j]+dp[P][k]) (j + k = i ,j>0,k>0,2<=i<=m,对于每一个i遍历每一种(j,k)组合)
这里的dp[P'father][j] j个城市一定是没有包括P城市的其他j个城市的最大值
直到遍历到root节点即可(dp[0][i])
3.输出dp[0][m]
7 4
2 2
0 1
0 4
2 1
7 1
7 6
2 2
[i]:v 表示 第i个节点的价值为v; [0]root没有价值相当于[0]:0
[0]root
/ \
[2]:1 [3]:4
/ | \
[1]:2 [4]:1 [7]:2
/ \
[5]:1 [6]:6
AC代码:
#include <bits/stdc++.h> using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 205; vector<int> v[maxn]; int dp[maxn][maxn]; int n,m; void dfs(int father){ for (int i = 0; i < v[father].size(); i++){ int child = v[father][i];//子节点 if(v[child].size() > 0) dfs(child); for(int j = m; j > 1; j--){//保证从父节点开始,至少取j个城市,j>1 至少包括了这个父节点 for(int k = 1; k < j; k++){//遍历每一种 k + j-k == j组合 dp[father][j] = max(dp[father][j] ,dp[father][k] + dp[child][j-k]); } } } } int main(){ while(scanf("%d%d",&n,&m),n+m){ for(int i = 0; i <= n; i++) v[i].clear(); m++;//因为数据给出的是森林,我们加入一个root节点,因此相当于允许多拿一个城市。 memset(dp,0,sizeof(dp)); for(int i = 1; i <= n ; i++){ int a,b; scanf("%d%d",&a,&b); v[a].push_back(i); for(int j = 1; j <= m; j++) dp[i][j] = b; //初始化时,每个节点,所有状态都是拿自己一个 } dfs(0); printf("%d\n",dp[0][m]); } return 0; }
相关文章推荐
- 2014蓝桥杯 小朋友排队
- VLC搭建RTSP服务器的过程 -测试通过
- 【Scala类型系统】自身类型(self type)引用
- php的一些小笔记--字符串
- html制作小常识
- 最常用标准库函数 (转)
- 模态窗口插件之Jbox
- 设计模式C++学习笔记之七(AbstractFactory抽象工厂模式)
- windows server 2012安装exchange 2010 sp3,owa密码过期无法使用
- java第八天
- HDOJ-1521 排列组合(母函数)
- fastjson转换json格式数据为List<HashMap>转换异常问题
- epoll 函数
- OpenStack(3)
- UITabBarItem UIBarButtonItem改变title颜色
- #Android学习#Animation简单使用
- 复利计算总结
- JS模块化工具requirejs教程01
- 复利计算总结
- 从今天开始学习写技术博客