您的位置:首页 > 其它

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

2018-10-30 22:08 381 查看

题意:有一棵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
,f
,dp
;
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

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: