首页 > 代码库 > hdu1561The more, The Better 树形dp
hdu1561The more, The Better 树形dp
/*
dp[i][j]表示第i个节点及其子树取j个所得的最大值
在第i个节点的儿子节点有多个,而对于每个儿子节点及其对应的子树中选几个节点才能得到最大值
可以用背包来做
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
#define maxn 210
int dp[maxn][maxn];//dp[i][j]表示第i个节点及其子树取j个所得的最大值
int value[maxn];
int vis[maxn];
vector<int> vec[maxn];
int N,M;
int dfs(int root,int remain)//remain表示到了这个节点最多能选多少节点
{
int i;int j,k;
int amount=0;//表示以该节点为根节点的子树的所有的节点的个数
for(i=0;i<vec[root].size();i++)
{
int next=vec[root][i];
int sum;
sum=dfs(next,remain-1);//表示这个这个子树的节点总数
amount+=sum;
for(j=min(remain-1,amount);j>=1;j--)
for(k=1;k<=sum&&k<=j;k++)
dp[root][j]=max((dp[root][j-k]+dp[next][k]),dp[root][j]);
}
for(j=min(amount,remain-1);j>=0;j--)//只能选了这个节点后才能选后面的节点
dp[root][j+1]=dp[root][j]+value[root];//所以该节点一定要加上
return amount+1;
}
int main()
{
/*freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);*/
while(scanf("%d%d",&N,&M),N||M)
{
int a,b;int i;
memset(value,0,sizeof(value));
memset(dp,0,sizeof(dp));
for(i=0;i<=N;i++)
vec[i].clear();
for(i=1;i<=N;i++)
{
scanf("%d%d",&a,&b);
vec[a].push_back(i);
value[i]=b;
}
dfs(0,M+1);
printf("%d\n",dp[0][M+1]);
}
return 0;
}
dp[i][j]表示第i个节点及其子树取j个所得的最大值
在第i个节点的儿子节点有多个,而对于每个儿子节点及其对应的子树中选几个节点才能得到最大值
可以用背包来做
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
#define maxn 210
int dp[maxn][maxn];//dp[i][j]表示第i个节点及其子树取j个所得的最大值
int value[maxn];
int vis[maxn];
vector<int> vec[maxn];
int N,M;
int dfs(int root,int remain)//remain表示到了这个节点最多能选多少节点
{
int i;int j,k;
int amount=0;//表示以该节点为根节点的子树的所有的节点的个数
for(i=0;i<vec[root].size();i++)
{
int next=vec[root][i];
int sum;
sum=dfs(next,remain-1);//表示这个这个子树的节点总数
amount+=sum;
for(j=min(remain-1,amount);j>=1;j--)
for(k=1;k<=sum&&k<=j;k++)
dp[root][j]=max((dp[root][j-k]+dp[next][k]),dp[root][j]);
}
for(j=min(amount,remain-1);j>=0;j--)//只能选了这个节点后才能选后面的节点
dp[root][j+1]=dp[root][j]+value[root];//所以该节点一定要加上
return amount+1;
}
int main()
{
/*freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);*/
while(scanf("%d%d",&N,&M),N||M)
{
int a,b;int i;
memset(value,0,sizeof(value));
memset(dp,0,sizeof(dp));
for(i=0;i<=N;i++)
vec[i].clear();
for(i=1;i<=N;i++)
{
scanf("%d%d",&a,&b);
vec[a].push_back(i);
value[i]=b;
}
dfs(0,M+1);
printf("%d\n",dp[0][M+1]);
}
return 0;
}
hdu1561The more, The Better 树形dp
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。