[HDOJ5534] Partial Tree(腦洞,完全背包)
阿新 • • 發佈:2017-05-09
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(腦洞,完全背包)