这道题是个很好做的二叉树
首先考虑给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;
}