HDU-1561 The more, The Better (树形DP+分组背包)

Posted 真正的强者,从不埋怨黎明前的黑暗!!!

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU-1561 The more, The Better (树形DP+分组背包)相关的知识,希望对你有一定的参考价值。

题目大意:给出一片森林,总共有n个点,并且都有权值。从中选出m个,使权值和最大。其中,选某个节点之前必须先选其父节点。

题目分析:给所有的树都加一个共同的权值为0的根节点,使森林变成一棵树。定义状态dp(u,k)表示在以节点u为根节点的组中选k个节点的最大权值。则状态转移方程为:

dp(u,k)=max(dp(u,k),dp(v,j)+dp(u,k-j),其中v是u的子节点。

 

代码如下:

# include<iostream>
# include<cstdio>
# include<cstring>
# include<algorithm>
using namespace std;

const int N=205;

struct Edge
{
	int to,nxt;
};
Edge e[N<<1];
int n,m,cnt;
int w[N];
int head[N];
int dp[N][N];

void add(int u,int v)
{
	e[cnt].to=v;
	e[cnt].nxt=head[u];
	head[u]=cnt++;
}

void init()
{
	int fa;
	cnt=w[0]=0;
	memset(head,-1,sizeof(head));
	memset(head,-1,sizeof(head));
	for(int i=1;i<=n;++i){
		scanf("%d%d",&fa,w+i);
		add(fa,i);
	}
}

void dfs(int u)
{
	dp[u][1]=w[u];
	for(int i=head[u];i!=-1;i=e[i].nxt){
		int v=e[i].to;
		dfs(v);
		for(int j=m+1;j>=2;--j){
			for(int k=1;k<j;++k)
				dp[u][j]=max(dp[u][j],dp[u][k]+dp[v][j-k]);
		}
	}
}

int solve()
{
	memset(dp,0,sizeof(dp));
	dfs(0);
	return dp[0][m+1];
}

int main()
{
	while(scanf("%d%d",&n,&m)&&(n+m))
	{
		init();
		printf("%d\n",solve());
	}
	return 0;
}

  

以上是关于HDU-1561 The more, The Better (树形DP+分组背包)的主要内容,如果未能解决你的问题,请参考以下文章

hdu 1561 The more, The Better(树形dp)

hdu1561The more, The Better(树形背包)

hdu1561 The more, The Better (树形DP)

hdu 1561 The more, The Better 树形dp

HDU1561 The more, The Better(树型DP)

hdu 1561 The more, The Better (依赖背包 树形dp)