http://acm.hdu.edu.cn/showproblem.php?pid=5534
考场上陷入了dp加入度的神奇思维。。。
题意
给
n
个点,要求生成一个
题解
一棵树,每个子树都可以看做是从根节点扩展出去的。
那么我们可以找到这样一个构树的方法:每次找一个叶节点,把它扩展成一个度为
k
,深度为
那么,我们令
f[n]
为
n
个节点的树的最大收益,每次枚举扩展节点的度即可。
注意:边界条件为
f[2] ,此时才能保证一定能找到叶子节点code
#include <algorithm> #include <cstdio> const int maxn = 3010; int n; int a[maxn], f[maxn]; void solve() { scanf("%d", &n); for (int i = 1; i < n; ++ i) scanf("%d", a+i); f[2] = 2 * a[1]; for (int i = 3; i <= n; ++ i) { f[i] = 0; for (int x = 1; x < i-1; ++ x) f[i] = std::max(f[i], f[i-x] - a[1] + a[x+1] + a[1] * x); // printf("%d\n", f[i]); } printf("%d\n", f[n]); } int main() { // freopen("1008.in", "r", stdin); int kase; scanf("%d", &kase); while (kase --) solve(); // for(;;); return 0; }