题意:给出一个n个节点的二叉树,中序遍历为1,2,3,......,n;每个节点都有一个分数(均为正整数),任一棵子树subtree的加分计算方法如下:
subtree的左子树的加分× subtree的右子树的加分+subtree的根的分数
求二叉树的最大分数和前序遍历?
思路:f[i][j]为从第i个到第j个节点的树最高分.
root[i][j]为从第i个到第j个节点的数根节点.
f[i][j]=max{f[i][o-1]*f[o+1][j]+f[o][o]}(o>=i,o<=j)
代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int f[105][105], d[105][105], ans=0;
void dfs(int i, int j) //前序遍历
{
if(i>=j)
{
if(i==j)
{
printf("%c%d",ans==0?'\0':' ',i);
}
ans++;
return ;
}
int v=d[i][j];
if(ans!=0)
printf(" %d",v);
else
{
printf("%d",v);
}
ans++;
dfs(i,v-1);
dfs(v+1,j);
}
int main()
{
int n;
scanf("%d",&n);
memset(d,-1,sizeof(d));
for(int i=1; i<=n; i++) //初始化
{
scanf("%d",&f[i][i]);
f[i][i-1]=1;
f[i+1][i]=1;
}
for(int i=n;i>=1;i--)
{
for(int j=i+1;j<=n;j++)
{
for(int o=i; o<=j; o++)
{
if(f[i][j]<f[i][o-1]*f[o+1][j]+f[o][o])
{
f[i][j]=f[i][o-1]*f[o+1][j]+f[o][o];
d[i][j]=o;
}
}
}
}
printf("%d\n",f[1][n]);
dfs(1,n);
printf("\n");
return 0;
}
京公网安备 11010502036488号