题解 | #牛牛种小树#

牛牛种小树

https://ac.nowcoder.com/acm/contest/11179/d

一共有n个点,因此度数和为2*(n-1),首先给每个点分一个度,保证最后形成的是一棵树。

分配n个度后还剩下m=2*(n-1)-n=n-1个度,剩下的这些度的最优分配方案用完全背包的方法dp求得。
背包的体积为m,每个物品的体积和价值分别为i-1(i个度有一个度在之前已经算过了)和w[i]

普通的完全背包不能保证最优选择方案能把背包的体积填满。但该题比较特殊,1~n-1体积的的物品都有,保证最优方案能够把背包填满:当选的物品体积j不足m时,能够在选一个体积为m-j的物品放入背包以增加总价值。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <climits>

#define x first
#define y second

using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;

const int N = 20010, M = 4, INF = 1e9;

LL f[N], w[N];
int n, m;

int main() {
    cin >> n;
    for (int i = 1; i <= n - 1; i ++)   cin >> w[i];

    m = 2 * (n - 1) - n;
    f[0] = 1ll * n * w[1];  //所有点的度初始化为1,保证没有孤立点
    for (int i = 2; i <= n - 1; i ++)
        for (int j = i - 1; j <= m; j ++)
            f[j] = max(f[j], f[j - i + 1] + w[i] - w[1]);//把一个度数为1的点换成度数为i的点

    cout << f[m];
    return 0;
}

全部评论

相关推荐

不愿透露姓名的神秘牛友
07-11 17:10
什么素质,我请问呢,要掉小珍珠了。。。又憋屈又生气
Steven267:这不喷回去?花钱是大爷,记住这个道理
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
07-10 12:05
点赞 评论 收藏
分享
头顶尖尖的程序员:我是26届的不太懂,25届不应该是找的正式工作吗?为什么还在找实习?大四还实习的话是为了能转正的的岗位吗
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务