• HDU 5534 完全背包


    Partial Tree

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
    Total Submission(s): 823    Accepted Submission(s): 407


    Problem Description
    In mathematics, and more specifically in graph theory, a tree is an undirected graph in which any two nodes are connected by exactly one path. In other words, any connected graph without simple cycles is a tree.

    You find a partial tree on the way home. This tree has n nodes but lacks of n1 edges. You want to complete this tree by adding n1 edges. There must be exactly one path between any two nodes after adding. As you know, there are nn2 ways to complete this tree, and you want to make the completed tree as cool as possible. The coolness of a tree is the sum of coolness of its nodes. The coolness of a node is f(d), where f is a predefined function and d is the degree of this node. What's the maximum coolness of the completed tree?
     
    Input
    The first line contains an integer T indicating the total number of test cases.
    Each test case starts with an integer n in one line,
    then one line with n1 integers f(1),f(2),,f(n1).

    1T2015
    2n2015
    0f(i)10000
    There are at most 10 test cases with n>100.
     
    Output
    For each test case, please output the maximum coolness of the completed tree in one line.
     
    Sample Input
    2 3 2 1 4 5 1 4
     
    Sample Output
    5 19
     
    题意:构造一颗最小生成树,但每个度数有个权值,使生成的权值最大。
     
    题解:总共有2*n-2度数,如果从正面出发,就是直接完全背包,可能会使某些点被孤立,不能保证最小度数为1.所以先给每个点分配一个度数,直接n*f[1],因为最后肯定有度数大于1的点,先找出此度数和f[1]的差值(可负可正),相当于权值成了差值。最后还有n-2个度。这时候再用完全背包。即第一个for从2开始枚举到n-1度,(好比每个度数有无穷多个)第二个for枚举n-2个度。
    状态转移方程:    dp[j]  = max(dp[j],dp[j-i+1]+f[i]).       为什么是j-i+1不是j-i呢,因为j是1到n-2中度,j-1相当于把那个1分配给一个度数已经为1的点,度数成了2,所以+f[2].
     
     
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    const int maxn = 2020;
    const int inf = 0x3f3f3f3f;
    int f[maxn];
    int dp[maxn];
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int n;
            int ans = 0;
            scanf("%d",&n);
            for(int i = 1; i<n; i++) scanf("%d",&f[i]);
            ans = n*f[1];
            for(int i = n-1; i>1; i--) f[i] -= f[1];
            for(int i = 1; i<=n-2; i++)
                dp[i] = -inf;
                dp[0] = 0;
            for(int i = 2; i <= n-1; i++)   //因为1度已定,所以从2枚举度数
                for(int j = 1; j <= n-2; j++) 
                    if(j>=i-1) dp[j] = max(dp[j],dp[j-i+1]+f[i]);
            printf("%d
    ",ans+dp[n-2]);
        }
        return 0;
    }
     
     
  • 相关阅读:
    mysql系列~mysqldump使用技巧
    mysql系列~logrotate
    最详细的经典双向电平转换电路的工作原理图文分析
    《USB应用分析精粹:从设备硬件、固件到主机程序设计》已经完稿
    Windows x86环境下使用QEMU安装arm架构银河麒麟V10操作系统
    不动产测绘包含哪些内容
    java问题收集
    java调用接口(rest-assured)
    java调用接口(okhttp )
    testng+allure
  • 原文地址:https://www.cnblogs.com/littlepear/p/5671054.html
Copyright © 2020-2023  润新知