二叉苹果树(树型DP+背包)

二叉苹果树

有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点)。这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1。

我们用一根树枝两端连接的结点的编号来描述一根树枝的位置。下面是一颗有4个树枝的树:

2   5

\  /

3  4

\  /

1

现在这颗树枝条太多了,需要剪枝。但是一些树枝上长有苹果。

给定需要保留的树枝数量,求出最多能留住多少苹果。

程序名:apple

输入格式:

第1行2个数,N和Q(1<=Q<= N,1<N<=100)。

N表示树的结点数,Q表示要保留的树枝数量。接下来N-1行描述树枝的信息。

每行3个整数,前两个是它连接的结点的编号。第3个数是这根树枝上苹果的数量。

每根树枝上的苹果不超过30000个。

输出格式:

一个数,最多能留住的苹果的数量。

输入样例:

5 2

1 3 1

1 4 10

2 3 20

3 5 20

输入样例:

21

解题思路:树型DP+背包求解。

f(i, j) 表示子树i,保留j个节点(注意是节点)的最大权值。每条边的权值,把它看作是连接的两个节点中的儿子节点的权值。

那么,就可以对所有i的子树做分组背包,即每个子树可以选择1,2,...j-1条边分配给它。

状态转移为:

f(i, j) = max{ max{f(i, j-k) + f(v, k) | 1<=k<j} | v是i的儿子}

ans = f(1, q+1)

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define MAX 105
#define INF 999999999
#define MP make_pair
typedef pair<int,int> PII;
vector<PII> adj[MAX];
int tot[MAX],f[MAX][MAX];
int max(int a,int b)
{
	return a>b?a:b;
}
int DFS(int u,int ff)
{
	tot[u]=1;
	int i,j,k;
	for(i=0;i<adj[u].size();i++)
	{
		int v=adj[u][i].first;
		if(v==ff)
			continue;
		tot[u]+=DFS(v,u);
	}
	for(i=0;i<adj[u].size();i++)
	{
		int v=adj[u][i].first;
		int w=adj[u][i].second;
		if(v==ff)
			continue;
		for(j=tot[u];j>1;j--)
		{
			for(k=1;(k<j)&&(k<=tot[v]);k++)
				f[u][j]=max(f[u][j],f[u][j-k]+f[v][k]+w);
		}
	}
	return tot[u];
}
int main()
{
	int i;
	int n,p,u,v,w;
	while(~scanf("%d%d",&n,&p))
	{
		for(i=0;i<MAX;i++)
			adj[i].clear();
		for(i=1;i<n;i++)
		{
			scanf("%d%d%d",&u,&v,&w);
			adj[u].push_back(MP(v,w));
			adj[v].push_back(MP(u,w));
		}
		memset(f,0,sizeof(f));
		DFS(1,-1);
		printf("%d\n",f[1][p+1]);
	}
	return 0;
}

二叉苹果树(树型DP+背包),布布扣,bubuko.com

时间: 2024-08-02 02:51:26

二叉苹果树(树型DP+背包)的相关文章

[Luogu2015]二叉苹果树(树形dp)

[Luogu2015] 二叉苹果树 题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来描述一根树枝的位置.下面是一颗有4个树枝的树 2 5 \ / 3 4 \ / 1 现在这颗树枝条太多了,需要剪枝.但是一些树枝上长有苹果. 给定需要保留的树枝数量,求出最多能留住多少苹果. 输入输出格式 输入格式: 第1行2个数,N和Q(1<=Q<= N,1&l

二叉苹果树(树形DP)

题面 原题 Solution 显然我们考虑这道题目可以很蠢的写一个Dp对吧. 考虑\(dp_i,j\)表示以i为根,保留j个节点的最大苹果数. 然后就可以树形Dp的写了. #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<algorithm> #include<iostream> #include<queue>

二叉苹果树|codevs5565|luoguP2015|树形DP|Elena

二叉苹果树 题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来描述一根树枝的位置.下面是一颗有4个树枝的树 2 5 \ / 3 4 \ / 1 现在这颗树枝条太多了,需要剪枝.但是一些树枝上长有苹果. 给定需要保留的树枝数量,求出最多能留住多少苹果. 输入输出格式 输入格式: 第1行2个数,N和Q(1<=Q<= N,1<N<=100)

初学树型dp

树型DP DFS的回溯是树形DP的重点以及核心,当回溯结束后,root的子树已经被遍历完并处理完了.这便是树形DP的最重要的特点 自己认为应该注意的点 好多人都说在更新当前节点时,它的儿子结点都给更新完了,实际上这并不准确.对于当前节点,我们需要dfs它的儿子,并且在dfs中进行dp.在此过程中并不是等到儿子都更新完我们才更新当前节点的信息(假设当前节点为x, 有儿子son1 , son2, son3, 且son1已经更新完了, 即x已有了son1的信息, son2刚刚更新完,即dfs正在son

二叉苹果树

题意/Description:     有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来描述一根树枝的位置.下面是一颗有4个树枝的树 2 5 \ / 3 4 \ / 1 现在这颗树枝条太多了,需要剪枝.但是一些树枝上长有苹果.给定需要保留的树枝数量,求出最多能留住多少苹果. 读入/Input:     第1行2个数,N和Q. N表示在树枚举的点数.Q表示应

HDU1561 The more, The Better(树型DP)

题目是有n个存有宝藏的城堡,攻克任何一个城堡都需要先攻克0个或其他1个城堡,问攻克m个城堡最多能得到多少宝藏. 题目给的城堡形成一个森林,添加一个超级根把森林连在一起就是树了,那么就考虑用树型DP: dp[u][m]表示以u结点为根的子树攻克m个结点的最大价值 但是这样转移太难了,根是从每个孩子通过各自分配若干的城堡去攻克转移的,一个排列组合数,阶乘,是指数级的时间复杂度! 看了题解,原来这是依赖背包,没看背包九讲..不过网上的博客似乎没说清楚,事实上这个状态应该是三个维度来表示: dp[u][

luogu P2015 二叉苹果树

P2015 二叉苹果树 题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来描述一根树枝的位置.下面是一颗有4个树枝的树 2        5 \     / 3   4 \ / 1 现在这颗树枝条太多了,需要剪枝.但是一些树枝上长有苹果. 给定需要保留的树枝数量,求出最多能留住多少苹果. 输入输出格式 输入格式: 第1行2个数,N和Q(1<=Q<

luoguP2015 二叉苹果树

luoguP2015 二叉苹果树 题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来描述一根树枝的位置.下面是一颗有4个树枝的树 2 5 \ / 3 4 \ / 1 现在这颗树枝条太多了,需要剪枝.但是一些树枝上长有苹果. 给定需要保留的树枝数量,求出最多能留住多少苹果. 输入输出格式 输入格式: 第1行2个数,N和Q(1<=Q<= N,1<

动态规划 树型DP

codves5565 二叉苹果树 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点)这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1.我们用一根树枝两端连接的结点的编号来描述一根树枝的位置.现在这颗树枝条太多了,需要剪枝.但是一些树枝上长有苹果.       给定需要保留的树枝数量,求出最多能留住多少苹果. 输入描述 Input Description 第1行2