这个题目听说是DP tree
DP tree自己还不是很熟悉,看了网上的解题报告出的题目,
有点戳,不解释,今后多看看这个方面的问题。
ans[i][j] = max(ans[i.leftchild][k] + ans[i.rightchild][j-k-1]) + i.val (i.leftchild表示其左孩子的编号,i.val表示i与其父节点相连的那条边上的苹果数),这样对于第i个节点ans[i][j]就会必取i与其父节点相连的那条边最终形成j条边。当j=0时,ans[i][j] = 0。
#include "stdio.h"
#include "string.h"
struct node
{
int l , r;
int s;
} tree[200];
int f[110][110] , apple[110][110];
int vis[100];
int n , q;
void create_tree(int root)
{
int i;
vis[root] = 1;
for( i = 1 ; i <= n ; i++ )
if(!vis[i] && apple[root][i] != -1)
{
if(tree[root].l==0)
tree[root].l=i;
else
tree[root].r=i;
tree[i].s = apple[root][i];
create_tree(i);
}
}
int tree_dp(int t , int k)
{
int i , ls , rs;
if(f[t][k] != -1)
return f[t][k];
if(t==0||k==0)
{
f[t][k] = 0;
return 0;
}
f[t][k] = 0;
for( i = 0 ; i <= k-1 ; i++ )
{
ls = tree_dp(tree[t].l,i);
rs = tree_dp(tree[t].r,k-1-i);
if( f[t][k] < ls+rs )
f[t][k] = ls+rs;
}
f[t][k] += tree[t].s;
return f[t][k];
}
int main()
{
int i , ans , a , b , s;
scanf("%d%d",&n,&q); q++;
memset(apple,-1,sizeof(apple));
for ( i = 1 ; i <= n-1 ; i++)
{
scanf("%d%d%d",&a,&b,&s);
apple[a][b]=s; apple[b][a]=s;
}
memset(tree,0,sizeof(tree));
memset(vis,0,sizeof(vis));
create_tree(1);
memset(f,-1,sizeof(f));
ans = tree_dp(1,q);
printf("%d\n",ans);
return 0;
}