Problem 1021 - Binary Tree

/*

Time Limit: 1000MS   Memory Limit: 65536KB   Difficulty:
Total Submit:
51  Accepted: 21  Special Judge: No


Description


Tiantian
is studying “Data Structure” now, and the Binary Tree took her attention. It is
a kind of data structure that has the property of tree and with its special
structure and operation. For its property: every node(except the root) in the
tree has only one parent and no more than two children, we may sometime
construct algorithms with the complex of O(nlogn) or O(logn) with the help of
it! How to construct a nice binary tree? Here comes the problem.

We have
got an ” inorder traversal” sequence of a binary tree, each element in the
sequence represents the power of the node. Your task is to build the tree with
the maximum cost.
A leaf gets the cost of its own power, and an empty
subtree gets the cost of 1.
How to calculate the power for building a binary
tree? Take the left subtree and the right subtree with cost of t1, t2, the root
power with k .
cost of the binary tree = t1 * t2 + k


Input

The input contains several test cases. Each test case
starts with a line containing an integer N (1<=N<=30), which describes the
number of the nodes in the binary tree. And then N integers follow in the next
line, separated by a space, to describe the N nodes’ power. Each power is a
positive integer no larger than 100. The total cost of building the binary tree
is no larger than 4,000,000,000.

Output

For each test case,
output only one line of one integer, to tell the maximum cost of building the
binary tree.

Sample Input

5
5 7 1 2 10

Sample
Output

145

*/

给出中序遍历,对n个结点的二叉树,具有相同中序遍历的有n!种,如果枚举显然不现实。假设dp[i][j]表示第i到第j个结点的最大cost值。可列方程:

dp[i][j]=max{ dp[i][j] , dp[i][k-1]*dp[k+1][j]+dp[k][k] };边界即为dp[i][i]=i;所以代码就不难写了。下面是AC代码。

 1 #include<stdio.h>
 2 int dp[110][110];
 3 int main()
 4 {
 5     int n,i,j,k;
 6     while(scanf("%d",&n)!=EOF)
 7     {
 8         for(i=1;i<=n;i++)
 9             scanf("%d",&dp[i][i]);
10         for(i=n-1;i>=1;i--)
11             for(j=i+1;j<=n;j++)
12             {
13                 dp[i][j]=0;
14                 for(k=i;k<=j;k++)
15                 {
16                     if(k==i) dp[i][j]=dp[i][j]>(1*dp[k+1][j]+dp[k][k])?dp[i][j]:(1*dp[k+1][j]+dp[k][k]);
17                     else if(k==j) dp[i][j]=dp[i][j]>(1*dp[i][k-1]+dp[k][k])?dp[i][j]:(1*dp[i][k-1]+dp[k][k]);
18                     else dp[i][j]=dp[i][j]>(dp[i][k-1]*dp[k+1][j]+dp[k][k])?dp[i][j]:(dp[i][k-1]*dp[k+1][j]+dp[k][k]);
19                 }
20             }
21         printf("%d\n",dp[1][n]);
22     }
23     return 0;
24 }

 

转载于:https://www.cnblogs.com/hjf007/p/3264909.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值