【LUOGU P2015】二叉苹果树(树形DP,二叉树)

传送门

这道题是个很好做的二叉树

首先考虑给DP数组下定义,一般来说树形DP的DP数组的第一维都是当前节点的编号。

这道题光一维肯定是不够的 ,那么加维,发现dp[i][j]表示当前节点为i,保留j个节点的最大苹果数量比较ok。
那么方程就显而易见了,dp[i][j]=max(dp[i][j],dp[i.lson][k]+dp[i.rson][j-k-1]+apple[i])。
另外,还可以在dfs时运用记忆化,可以大大提高速度 。
再提一句,由于题目中给的权值在边上,让人特别难受,于是,我们把权值转化到儿子上会方便操作。

#include<bits/stdc++.h>
using namespace std;
const int N=150;
int n,q,dp[N][N];
struct node
{
	int lson;
	int rson;
	int val;
}tree[N*20];
int dfs(int now,int point)
{
	if(now==0||point==0)
	{
		return 0;
	}
	if(tree[now].lson==0&&tree[now].rson==0)
	{
		return tree[now].val;
	}
	if(dp[now][point]>0)	return dp[now][point];//记忆化 
	for(int k=0;k<point;k++)	//枚举方程中的k 
	{
		dp[now][point]=max(dp[now][point],dfs(tree[now].lson,k)+dfs(tree[now].rson,point-k-1)+tree[now].val); 
	}
	return dp[now][point];
}
int main()
{	cin>>n>>q;
	for(int i=1;i<=n-1;i++)
	{
		int fa,son,v;
		cin>>fa>>son>>v;
		tree[son].val=v;
		if(tree[fa].lson==0) tree[fa].lson=son;
		else tree[fa].rson=son;
	}
	cout<<dfs(1,q+1);//注意是q+1 因为把边变成了点 
	return 0;
}
posted @ 2018-07-30 17:06  Patrickpwq  阅读(135)  评论(0编辑  收藏  举报