1. 程式人生 > >【HDOJ5534】Partial Tree(樹,背包DP)

【HDOJ5534】Partial Tree(樹,背包DP)

bits scanf mat 就是 long man scan string using

題意:有一棵n個點的形態不定的樹,每個度為i的節點會使樹的權值增加f[i],求樹的最大權值

n<=2015,0<=f[i]<=1e4

思路:對不起隊友,我再強一點就能賽中出這題了

顯然每個點的度至少為1,且度數為1的節點至少有2個(From 隊友)

有一個結論:給每個點都分配1個度,剩余的度任意分配,一定能構造出對應的方案

仔細想想題面裏的生成樹數量不就在暗示我有類似Prufer序的性質麽……序列與構造一一對應……唉太菜了

然後就是經典的完全背包問題了

每個點分配一個度之後還剩余n-2個度,每個點的分配到1之後多出來的度是[0,n-2]

 1 #include<iostream>
 2
#include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<ctime> 6 #include<cmath> 7 #include<algorithm> 8 #include<iomanip> 9 #include<vector> 10 #include<map> 11 #include<set> 12 #include<bitset> 13 #include<queue> 14
#include<stack> 15 using namespace std; 16 typedef long long ll; 17 typedef unsigned int uint; 18 typedef unsigned long long ull; 19 typedef pair<int,int> PII; 20 typedef vector<int> VI; 21 #define fi first 22 #define se second 23 #define MP make_pair 24 #define N 2100 25 #define M 110000 26
#define eps 1e-8 27 #define pi acos(-1) 28 #define oo 1000000000 29 #define MOD 10007 30 31 int a[N],f[N],dp[N]; 32 33 34 int main() 35 { 36 //freopen("hdoj5534.in","r",stdin); 37 //freopen("hdoj5534.out","w",stdout); 38 int cas; 39 scanf("%d",&cas); 40 for(int v=1;v<=cas;v++) 41 { 42 int n; 43 scanf("%d",&n); 44 for(int i=1;i<n;i++) scanf("%d",&a[i]); 45 for(int i=1;i<n;i++) f[i-1]=a[i]-a[1]; 46 int m=n-2; 47 memset(dp,0,sizeof(dp)); 48 dp[0]=n*a[1]; 49 for(int i=1;i<=m;i++) 50 for(int j=1;j<=i;j++) dp[i]=max(dp[i],dp[i-j]+f[j]); 51 printf("%d\n",dp[m]); 52 } 53 return 0; 54 } 55 56

【HDOJ5534】Partial Tree(樹,背包DP)