我们可以轻松地发现这道题是一道dp的题目
对于整张图来说,总共有2*n-2地度数,由于每一个点都至少有一个度数,我们就只剩下n-2的度数可以进行自由分配
我们将每个点看做一个点加上一条没有连上其他点的边,然后在更新的时候将所有点联向当前树的叶子节点上,然后根据其度数做一下背包就好了
f[i] 表示树上已经有i 个点的最佳权值
假设度数为i的贡献为a[i],当一个节点插入的时候,会损失a[1]的价值,增加a[i-j+1]的价值,所以转移方程为
f[i]=max(f[i],f[j]+a[i-j+1]-a[1]),1<=j<=i;
然后直接转移即可
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#define LL long long
const int MAXN=1e4+7;
const LL INF=1e18;
LL f[MAXN];
int a[MAXN];
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
memset(f,0x80,sizeof f);
int cnt=0;
int x=0;
for(int i=1;i<n;i++)
{
scanf("%d",a+i);
}
f[0]=0;
for(int i=1;i<=n-1;i++)
{
for(int j=i;j<=n-2;j++)
{
f[j]=std::max(f[j],f[j-i]+1ll*a[i+1]-a[1]);
}
}
LL ans=f[n-2]+1ll*n*a[1];
std::cout<<ans<<std::endl;
}
return 0;
}
京公网安备 11010502036488号