牛牛种小树
Posted Jozky86
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛牛种小树相关的知识,希望对你有一定的参考价值。
题意:
他打算用他得到的米粒去构造一棵有n个节点的树,并使得它的价值最大。
设f(d)表示树上度数为d的一个点能够获取的最大价值。则这棵树的价值为
∑
i
=
1
n
f
(
d
i
)
\\sum_{i=1}^nf(d_{i})
∑i=1nf(di),其中
d
i
d_{i}
di表示第i个点的度数
题解:
一颗n个节点的数,所有点的度数之和为2n-2
那我们可以反着理解,将这2n-2个度数分配给n个点,当然每个点至少度数为1,所以我们先给每个点分一个度数,这样问题就是n-2个度数分配给n个点,f[i]表示度为i的节点的价值。这个问题就很类似完全背包了,f[i]是价值,空间为n-2,有n-2个物品(对应度数为2和度数为n-1,因为度数为1的提前处理了)。
注意度数为1的提前处理了,所以每次加入一堆时需要减去f(1)
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#define int long long
using namespace std;
int T,i,s,j,n,a[12020],f[12020];
signed main()
{
scanf("%lld",&n);
for (i=1;i<=n-1;i++)
{
scanf("%lld",&a[i]);
if (i!=1) a[i]-=a[1];
}
s=a[1]*n;
for (i=1;i<=n-2;i++) f[i]=-2e18;
f[0]=0;
for (i=2;i<=n-1;i++)
for (j=i-1;j<=n-2;j++)
f[j]=max(f[j],f[j-i+1]+a[i]);
printf("%lld\\n",s+f[n-2]);
return 0;
}
以上是关于牛牛种小树的主要内容,如果未能解决你的问题,请参考以下文章