• 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;
    }
     
     
  • 相关阅读:
    ios -为什么用WKWebView加载相同的html文本,有时展示的内容却不一样。
    weex
    [Objective-C 面试简要笔记]
    [iOS 基于CoreBluetooth的蓝牙4.0通讯]
    [SVN Mac自带SVN结合新浪SAE进行代码管理]
    [SVN Mac的SVN使用]
    [iOS dispatch_once创建单例]
    [iOS UI设计笔记整理汇总]
    [iOS 视频流开发-获得视频帧处理]
    [iOS OpenCV错误解决]
  • 原文地址:https://www.cnblogs.com/littlepear/p/5671054.html
Copyright © 2020-2023  润新知