设一个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的前序遍历
Input
第1行:一个整数n(n<30),为节点个数。 第2行:n个用空格隔开的整数,为每个节点的分数(分数<100)。
Output
第1行:一个整数,为最高加分(结果不会超过4,000,000,000)。 第2行:n个用空格隔开的整数,为该树的前序遍历。
Sample Input
55 7 1 2 10
Sample Output
1453 1 2 4 5
//============================================================================ // Name : 加分二叉树new.cpp // Author : // Version : // Copyright : Your copyright notice // Description : Hello World in C++, Ansi-style //============================================================================ #include <iostream> using namespace std; int a[100]; int n; int Max; int f[100][100]; int path[100][100]; const int MAX=10000; void print(int begin,int end) { if(begin>end) return; if(!path[begin][end]) return; int i=path[begin][end]; cout<<i<<" "; print(begin,i-1); print(i+1,end); } void compute_f(int begin,int end) { if(begin>end) { f[begin][end]=1; path[begin][end]=0; return; } if(begin==end) { f[begin][end]=a[begin]; path[begin][end]=begin; return ; } for(int i=begin;i<=end;i++) { compute_f(begin,i-1); compute_f(i+1,end); if(f[begin][i-1]*f[i+1][end]+a[i]>f[begin][end]) { f[begin][end]=f[begin][i-1]*f[i+1][end]+a[i]; path[begin][end]=i; } } cout<<"f["<<begin<<"]["<<end<<"]="<<f[begin][end]<<endl; } int main() { n=5; a[1]=5; a[2]=7; a[3]=1; a[4]=2; a[5]=10; Max=-MAX; compute_f(1,5); cout<<f[1][5]<<endl; print(1,5); return 0; }