HDU - 5534 Partial Tree (完全背包,物品价值包含负数)

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条边要连接所有的点,所以我们可以先让每条边与一个点一对一连接,那么我们得到(n-1)个度为一的点,剩下一个度为0的是根节点,然后我们让一条边与根节点相连,那么现在n个点的度都为一,因为所有边共产生2*(n-1)度所以剩下(n-2)度,所以问题转化成把(n-2)个度分给n个点,使得结果的f(d)和最大。

这明显是一个完全背包问题了。可以把度数想成weight,f(d)想成value,(n-2)为背包最大容量,那么这就是一个基础的完全背包放东西模板。

注意这里d 和 f(d)都为原值与1和f(1)的差值,也因此会有负数。

代码:

#include 
#include 
#include 

using namespace std;

const int MAXN = 2020;
const long long INF = 0x3f3f3f3f3f3f3f3f;

struct D{
	long long f,d;
}board[MAXN];

long long dp[MAXN*2];

int main(){	
	
	int T,N;
	scanf("%d",&T);
	while(T--){
		memset(dp,-INF,sizeof dp);
		scanf("%d",&N);
		scanf("%lld",&board[1].f);
		board[1].d = 1;
		for(int i=2 ; i

 

你可能感兴趣的:(DP)