zoukankan      html  css  js  c++  java
  • [HDOJ5534] Partial Tree(脑洞,完全背包)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5534

    题意:给n个点,希望用这n个点构成一棵树,然后每一个度有一个价值,希望价值总和最大。问最大价值。

    知道一棵树的度和为2*n-2,并且每一个点必然有1的度,在每个点持有1度的情况下,相当于给n个点分n-2个度。试验发现,无论如何分配,都可以构成一棵树。

    这样问题就变成了容量为n-2的背包,有2~n-2个物品,价值分别为v(i)的完全背包问题。

    先让所有价值减去度为1的价值,做完全背包后再加回去。注意做完全背包的时候要默认度为1,所以转移为dp[i] = max(dp[i], dp[i-j]+v[j+1])。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int maxn = 2020;
     5 int n;
     6 int v[maxn];
     7 int dp[maxn];
     8 
     9 int main() {
    10     // freopen("in", "r", stdin);
    11     int T;
    12     scanf("%d", &T);
    13     while(T--) {
    14         scanf("%d", &n);
    15         for(int i = 1; i < n; i++) {
    16             scanf("%d", &v[i]);
    17             if(i != 1) v[i] -= v[1];
    18         }
    19         for(int i = 1; i <= n - 2; i++) dp[i] = -0x7f7f7f7f;
    20         dp[0] = 0;
    21         for(int i = 1; i <= n - 2; i++) {
    22             for(int j = 1; j <= i; j++) {
    23                 dp[i] = max(dp[i], dp[i-j]+v[j+1]);
    24             }
    25         }
    26         printf("%d
    ", dp[n-2]+n*v[1]);
    27     }
    28     return 0;
    29 }
  • 相关阅读:
    移动方法
    linux主编号的动态分配
    linux 分配和释放设备编号
    linux设备编号的内部表示
    linux主次编号
    linux模块参数
    linux scull 的设计
    linux模块加载竞争
    linux清理函数
    linux初始化中的错误处理
  • 原文地址:https://www.cnblogs.com/kirai/p/6828492.html
Copyright © 2011-2022 走看看