HDU 5534 Partial Tree (背包+trick)

来源:互联网 发布:淘宝试衣模特招聘合肥 编辑:程序博客网 时间:2024/06/05 05:23

题意:给你n个结点,告诉你如果一个结点的度数为d,那么它的价值为f(d),告诉你度数为1到n-1的f(d),问你,让你通过这n个结点构造出一棵树使得它的结点价值之和最大,价值最大是多少。( 1≤T≤2015,2≤n≤2015,0≤f(i)≤10000)

思路:
  很容易写出
  dp[i][j]:1-i度,所能形成的度数为j的最大价值。
  然后,我们很容易发现这就是个完全背包。但是。我们没有办法限制结点个数,比如样例1,按照完全背包,它会由6个度推出,6×1=6的答案,然而实际上我们最多只能有3个结点,那怎么办呢。
  这个题的trick就是,先构造每个点1个度,然后再跑完全背包。
  

#include <bits/stdc++.h>using namespace std;const int maxn = 5000 + 5;int dp[maxn], a[maxn];int main(){    int T;    scanf("%d", &T);    while(T--)    {        int n;        scanf("%d", &n);        for(int i = 1; i <= n - 1; i++) scanf("%d", &a[i]);        int ans = a[1] * n;        int degree = 2 * (n - 1) - n;        for(int i = 0; i <= n; i++)  dp[i] = -0x3f3f3f3f;        dp[0] = 0;        for(int i = 2; i <= n - 1; i++)        {            for(int j = i - 1; j <= degree; j++)            {                dp[j] = max(dp[j], dp[j - (i - 1)] + a[i] - a[1]);            }        }        printf("%d\n", ans + dp[degree]);    }    return 0;}
原创粉丝点击