您的位置:首页 > 其它

HDU 5534 Partial Tree(动态规划)

2016-07-05 18:44 281 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5534

题面:

Partial Tree

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)

Total Submission(s): 763    Accepted Submission(s): 374


[align=left]Problem Description[/align]
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?
 

[align=left]Input[/align]
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.
 

[align=left]Output[/align]
For each test case, please output the maximum coolness of the completed tree in one line.
 

[align=left]Sample Input[/align]

2
3
2 1
4
5 1 4

 

[align=left]Sample Output[/align]

5
19

 

[align=left]Source[/align]
2015ACM/ICPC亚洲区长春站-重现赛(感谢东北师大)

 

题意:

    给定一颗无向树的节点数和各个度对应的权值,定义酷度为每个节点的度数乘以相应的度对应的权值的总和,求最大酷度。

解题:

    比较直接的想法是dp[i][j],表示前i个节点分配了j点度数能获取的最大值,写法清晰明了,可惜复杂度为n^3,明显超时。

    结合树的特殊结构,每个节点的度数最少为1,因此预先给每个节点分配一点度数,随后再将剩余的2*(n-1)-n点度数分配,使之得到最大的酷度。

    状态转移方程可以改进为dp[i],代表在原来均分了n点度数的基础上,再分配i点度数所能获取的最大酷度。因为已经保障了每个节点至少为1度,后续分配也不会出现多次替换的情况,因此省却了位置这一维,复杂度降为n^2.问题得解。

    dp[i]=max(dp[i],dp[i-j]+f[j+1]-f[1]);

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include <algorithm>
using namespace std;
int f[2020],dp[2020];
int main()
{
int t,n,lim;
scanf("%d",&t);
while(t--)
{
memset(dp,0,sizeof(dp));
scanf("%d",&n);
for(int i=1;i<n;i++)
scanf("%d",&f[i]);
dp[0]=n*f[1];
for(int i=1;i<=n-2;i++)
for(int k=1;k<=i;k++)
dp[i]=max(dp[i],dp[i-k]+f[k+1]-f[1]);
printf("%d\n",dp[n-2]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  hdu 动态规划