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
背包题,但是跟平常的背包不一样的地方在于,她限制了拿的物品的数量,
给n-1个物品,每个物品的花费是c[i],价值是w[i],取n个物品,在花费为
2×n-2的情况下,要求这个n-1个物品的价值和最大,
对于普通的完全背包是不会限制拿的物品的个数的,
所以想要转化成普通的背包,就要把这个限制去掉,
有一个方法可以做到,那就是先取n-1个花费为1的物品,那么把剩余n-2的费用进行
完全背包就好了,如果你选择了第i个物品,那么花费其实是c[i]-1,得到的价值是
w[i]-w[1];这样就把这题转化成完全背包了。
#include<bits/stdc++.h>
using namespace std;
const int N = 2100;
int dp[2][N];
int f[N];
int main(){
int T;
cin >> T;
while(T--){
int n;
scanf("%d",&n);
for(int i = 1;i < n;i ++){
scanf("%d",&f[i]);
}
memset(dp,0,sizeof(dp));
dp[0][0] = f[1]*n;
int tmp = 0;
for(int i = 2;i <= n-1;i ++){
tmp = 1-tmp;
for(int j = 0;j <= n-2;j ++) {
if(j < i-1){
dp[tmp][j] = dp[1-tmp][j];
}
else
dp[tmp][j] = max(dp[1-tmp][j],dp[tmp][j-i+1]+f[i]-f[1]);
}
}
printf("%d\n",dp[tmp][n-2]);
}
return 0;
}