Partial Tree
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 599 Accepted Submission(s): 294
Problem Description
In mathematics, and more specifically in graph theory, a tree is an undirected graph in which any two nodes are connected by exactly one path. In other words, any connected graph without simple cycles is a tree.
You find a partial tree on the way home. This tree has n nodes but lacks of n−1 edges. You want to complete this tree by adding n−1 edges. There must be exactly one path between any two nodes after adding. As you know, there are nn−2 ways to complete this tree, and you want to make the completed tree as cool as possible. The coolness of a tree is the sum of coolness of its nodes. The coolness of a node is f(d) , where f is a predefined function and d is the degree of this node. What's the maximum coolness of the completed tree?
You find a partial tree on the way home. This tree has n nodes but lacks of n−1 edges. You want to complete this tree by adding n−1 edges. There must be exactly one path between any two nodes after adding. As you know, there are nn−2 ways to complete this tree, and you want to make the completed tree as cool as possible. The coolness of a tree is the sum of coolness of its nodes. The coolness of a node is f(d) , where f is a predefined function and d is the degree of this node. What's the maximum coolness of the completed tree?
Input
The first line contains an integer
T
indicating the total number of test cases.
Each test case starts with an integer n in one line,
then one line with n−1 integers f(1),f(2),…,f(n−1) .
1≤T≤2015
2≤n≤2015
0≤f(i)≤10000
There are at most 10 test cases with n>100 .
Each test case starts with an integer n in one line,
then one line with n−1 integers f(1),f(2),…,f(n−1) .
1≤T≤2015
2≤n≤2015
0≤f(i)≤10000
There are at most 10 test cases with n>100 .
Output
For each test case, please output the maximum coolness of the completed tree in one line.
Sample Input
2 3 2 1 4 5 1 4
Sample Output
5 19
Source
2015ACM/ICPC亚洲区长春站-重现赛(感谢东北师大)
题意:构建一个n个点的树,每个点的度i的价值为f(i),求能获得的最大价值。
思路:树的度总和是2*(n-1),把题目看作是将2*(n-1)个物品放进n个背包,看作背包问题,但是这样还有个条件限制就是每个背包至少要有1个物品(1个度),这样做要用O(n^3),但如果事先每个点分配一个度,那么其他的度就可以任意分配了,现在题目可以看作,把n-2个物品放进1个背包里,并且f(i)都要减去f(1)。
#include <stdio.h>
#include <string.h>
#define maxn 2050
#define ll long long int
const int inf = 0x3f3f3f3f;
ll w[maxn], dp[maxn];
ll max(ll a, ll b){
return a>b?a:b;
}
int main()
{
ll T, n, i, j, v;
scanf("%I64d", &T);
while(T--){
scanf("%I64d", &n);
for(i = 1;i < n;i++)
scanf("%I64d", &w[i]);
memset(dp, 0, sizeof dp);
dp[0] = n*w[1];//先每个点分配一个度
v = 2*(n - 1) - n;//现在的每个点最多分配n - 2个度
for(i = 2;i < n;i++)
for(j = i - 1;j <= v;j++)//原先已经分配了一个度,要减去1
dp[j] = max(dp[j], dp[j - i + 1] + w[i] - w[1]);//贡献值都要减去w[1]
printf("%I64d\n", dp[v]);
}
}