标签:
【问题描述】
设一个n个节点的二叉树tree的中序遍历为(l,2,3,…,n),其中数字1,2,3,…,n为节点编号。
每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都
有一个加分,任一棵子树subtree(也包含tree本身)的加分计算方法如下:
subtree的左子树的加分× subtree的右子树的加分+subtree的根的分数
若某个子树为空,规定其加分为1,叶子的加分就是叶节点本身的分数。不考虑它的空子树。
试求一棵符合中序遍历为(1,2,3,…,n)且加分最高的二叉树tree。要求输出;
(1)tree的最高加分
(2)tree的前序遍历
【输入格式】
第1行:一个整数n(n<30),为节点个数。
第2行:n个用空格隔开的整数,为每个节点的分数(分数<100)。
【输出格式】
第1行:一个整数,为最高加分(结果不会超过4,000,000,000)。
第2行:n个用空格隔开的整数,为该树的前序遍历。
【输入样例】
5
5 7 1 2 10
【输出样例】
145
3 1 2 4 5
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int f[50][50];
int tree[50][50];
int node[50][2];
void init()
{
memset(tree, 0, sizeof(tree));
memset(f, 0, sizeof(f));
}
int solve(int l,int r)
{
if (f[l][r]) return f[l][r];
for (int i = l; i <= r; i++)
{
int x = solve(l, i - 1);
int y = solve(i + 1, r);
if (x == 0) x = 1;
if (y == 0) y = 1;
if (x * y + f[i][i] > f[l][r])
{
f[l][r] = x*y + f[i][i];
tree[l][r] = i;
}
}
return f[l][r];
}
void print(int num,int l,int r)
{
if (tree[l][num - 1])
{
printf(" %d", tree[l][num - 1]);
print(tree[l][num-1], l, num-1);
}
if (tree[num + 1][r])
{
printf(" %d", tree[num + 1][r]);
print(tree[num + 1][r], num + 1, r);
}
}
int main()
{
int n;
freopen("in.txt", "r", stdin);
while (~scanf("%d", &n))
{
init();
for (int i = 1; i <= n; i++)
{
scanf("%d", &f[i][i]);
tree[i][i] = i;
};
cout << solve(1, n) << endl;
printf("%d", tree[1][n]);
print(tree[1][n], 1, n);
printf("\n");
}
return 0;
}
标签:
原文地址:http://blog.csdn.net/qq_31457873/article/details/51364814