Partial Tree
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 228 Accepted Submission(s): 138
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?
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.
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亚洲区长春站-重现赛(感谢东北师大)
题意:一个树的权值被定义为sigma(f(di), 1<=i<=n)其中di是第i个点的度数,求一个n个点的数的最大权值
分析:先把每个点的度数当成1,然后问题转化为总度数为2n-2,现有度数n,求增加n-2度数的最大权值
dp[i]表示增加i度数的最大权值
dp[i] = max(f[i+1], dp[j]+dp[i-j]), 1<=j<=i/2
完了
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <ctime> 6 #include <iostream> 7 #include <map> 8 #include <set> 9 #include <algorithm> 10 #include <vector> 11 #include <deque> 12 #include <queue> 13 #include <stack> 14 using namespace std; 15 typedef long long LL; 16 typedef double DB; 17 #define MIT (2147483647) 18 #define MLL (1000000000000000001LL) 19 #define INF (1000000001) 20 #define For(i, s, t) for(int i = (s); i <= (t); i ++) 21 #define Ford(i, s, t) for(int i = (s); i >= (t); i --) 22 #define Rep(i, n) for(int i = (0); i < (n); i ++) 23 #define Repn(i, n) for(int i = (n)-1; i >= (0); i --) 24 #define mk make_pair 25 #define ft first 26 #define sd second 27 #define puf push_front 28 #define pub push_back 29 #define pof pop_front 30 #define pob pop_back 31 #define sz(x) ((int) (x).size()) 32 #define clr(x, y) (memset(x, y, sizeof(x))) 33 inline void SetIO(string Name) 34 { 35 string Input = Name + ".in"; 36 string Output = Name + ".out"; 37 freopen(Input.c_str(), "r", stdin); 38 freopen(Output.c_str(), "w", stdout); 39 } 40 41 inline int Getint() 42 { 43 char ch = ‘ ‘; 44 int Ret = 0; 45 bool Flag = 0; 46 while(!(ch >= ‘0‘ && ch <= ‘9‘)) 47 { 48 if(ch == ‘-‘) Flag ^= 1; 49 ch = getchar(); 50 } 51 while(ch >= ‘0‘ && ch <= ‘9‘) 52 { 53 Ret = Ret * 10 + ch - ‘0‘; 54 ch = getchar(); 55 } 56 return Ret; 57 } 58 59 const int N = 2050; 60 int n, F[N]; 61 int Dp[N]; 62 63 inline void Solve(); 64 65 inline void Input() 66 { 67 int TestNumber = Getint(); 68 while(TestNumber--) 69 { 70 n = Getint(); 71 For(i, 1, n - 1) F[i] = Getint(); 72 Solve(); 73 } 74 } 75 76 inline void Solve() 77 { 78 For(i, 2, n - 1) F[i] -= F[1]; 79 Dp[0] = 0; 80 For(i, 1, n - 2) 81 { 82 Dp[i] = F[i + 1]; 83 For(j, 1, (i / 2) + 1) 84 Dp[i] = max(Dp[i], Dp[j] + Dp[i - j]); 85 } 86 printf("%d\n", Dp[n - 2] + n * F[1]); 87 } 88 89 int main() 90 { 91 Input(); 92 //Solve(); 93 return 0; 94 }