zoukankan      html  css  js  c++  java
  • 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;
    }
     
     
  • 相关阅读:
    自实现的DNetStopWatch类
    IL Discovery 系列三 《为什么在遍历List<T>对象时同时删除其中项会抛出异常》
    高效的线程安全队列ConcurrentQueue<T>(上)
    .NET中Object.Equals()方法与Object.ReferenceEquals()方法
    麻省理工学院(MIT)的开放课程(OCW)真的不错,其音像资料
    Eclipse快捷键大全
    MyEclipse快捷键大全
    c#单文件上传下载源代码
    Tomcat 配置集锦
    asp.net(C#)多文件上传(源代码)vs2008
  • 原文地址:https://www.cnblogs.com/littlepear/p/5671054.html
Copyright © 2011-2022 走看看