[HDU1561]The more, The Better

本文介绍了一种解决有依赖背包问题的方法,使用树形动态规划(DP)。通过将问题转化为求解森林中最大价值组合,文章详细阐述了如何设置状态转移方程,并提供了C++代码实现,最终求得打掉指定数量城堡的最大价值。

题目大意:有n座城堡,每座城堡打掉后能获得一个价值,但某些城堡需要在打掉另一个城堡后才能打,求打掉m座城堡能获得的最大价值。

解题思路:这是一道有依赖的背包问题,可以用树形dp的方式做。

设f[i][j]表示打掉以i为根的子树中的j个城堡所获得的最大价值,则有f[i][j]=max(f[i][j-k]+f[son][k]);(0≤k≤j-1,son是i的子节点)

由于题目给出的是森林,我们把所有树的根节点连到0号节点上,就变成一棵树了。那么m就要相应的加1。最后的答案为f[0][m](m为加1后的)。

时间复杂度$O(nm^2)$。

C++ Code:

 

#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
#define max(a,b) (((a)>(b))?(a):(b))
int f[205][205],n,m;
vector<int>e[205];
void dfs(int root){
	for(int i=0;i<e[root].size();++i){
		int son=e[root][i];
		dfs(son);
		for(int j=m;j>1;--j)
		for(int k=0;k<j;++k)
		f[root][j]=max(f[root][j],f[root][j-k]+f[son][k]);
	}
}
int main(){
	while(scanf("%d%d",&n,&m)&&n+m){
		++m;
		memset(f,0,sizeof f);
		for(int i=0;i<=201;++i)e[i].clear();
		for(int i=1;i<=n;++i){
			int x,y;
			scanf("%d%d",&x,&y);
			e[x].push_back(i);
			for(int j=1;j<=m;++j)
			f[i][j]=y;
		}
		dfs(0);
		printf("%d\n",f[0][m]);
	}
	return 0;
} 

 

转载于:https://www.cnblogs.com/Mrsrz/p/7297537.html

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值