1. 程式人生 > >[HDOJ5534] Partial Tree(腦洞,完全背包)

[HDOJ5534] Partial Tree(腦洞,完全背包)

logs include 每一個 log php color tdi 發現 clas

題目鏈接: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\n", dp[n-2]+n*v[1]); 27 } 28 return 0; 29 }

[HDOJ5534] Partial Tree(腦洞,完全背包)