比赛 动规 评测结果 AAAAAAA
题目名称 加分二叉树 最终得分 100
用户昵称 Hyoi_ctime 运行时间 0.001 s
代码语言 C++ 内存使用 0.33 MiB
提交时间 2017-06-18 21:32:21
显示代码纯文本
#include<iostream>  
#include<iomanip>  
#include<cstring>  
#include<cstdio>  
#include<cmath>  
#include<memory>  
#include<algorithm>  
#include<string>  
#include<climits>  
#include<queue>  
#include<vector>  
#include<cstdlib>  
#include<map>  
using namespace std;  
  
const int ee=50,e=-999999999;  
int n;  
int a[ee]={0},f[ee][ee],root[ee][ee]={0};//f(i,j)中序遍历为i,i+1,…,j的二叉树的最大加分  
  
//**若根节点的下表是k,则左端点的是k-1,右端点是k+1;  
void front(int x,int y)  
{  
    if(root[x][y]!=0)  
        cout<<root[x][y]<<' ';  
    if(root[x][root[x][y]-1]!=0)    front(x,root[x][y]-1);  
    if(root[root[x][y]+1][y]!=0)    front(root[x][y]+1,y);  
}  
  
int main()  
{  

	freopen("jfecs.in","r",stdin);
	freopen("jfecs.out","w",stdout);
    //memset 赋初值不能为1 memset(f,1,sizeof(f));  
    cin>>n;  
  
    for(int i=0;i<=n;i++)  
    {  
        for(int j=0;j<=n;j++)  
            f[i][j]=1;  
    }  
    for(int i=1;i<=n;i++)  
    {  
        cin>>a[i];  
        f[i][i]=a[i];  
        root[i][i]=i;  
    }  
    //区间长度  
    for(int len=1;len<=n;len++)  
    {  
        //区间起点  
        for(int i=1;i<=n;i++)  
        {  
            //终点  
            int j=i+len;  
            if(j<=n)  
            {  
                int temp=e;  
                //因为是中序排列  
                for(int k=i;k<=j;k++)  
                {  
                    if(temp < (f[i][k-1]*f[k+1][j]+a[k]))  
                    {  
                        temp=f[i][k-1]*f[k+1][j]+a[k];  
                        root[i][j]=k;  
                    }  
                }  
                f[i][j]=temp;  
            }  
        }  
    }  
    cout<<f[1][n];  
  
    //前序遍历  
    cout<<endl;  
    front(1,n);  
  
return 0;  
}