加分二叉树
LOJ链接
洛谷链接
1.本题还是采用DP的做法。
2.f[i][j]表示顶点i到顶点j所组成的子树的最大值
3.root[i][j]表示根编号
4.具体细节在程序里
//加分二叉树,f[i][j]表示顶点i~顶点j组成的子树的最大值,root是编号
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll f[35][35],root[35][35];
inline ll search(int l,int r)
{
int k;
ll now,ans;
if(l>r) return 1;//空子树的值为1
if(f[l][r]==-1)//未处理过
for(k=l;k<=r;k++)//穷举每一个可能的子根k
{
now=search(l,k-1)*search(k+1,r)+f[k][k];//计算值
if(now>f[l][r])
{
f[l][r]=now;//更新最大值
root[l][r]=k;
}
}
return f[l][r];
}
inline void print(int l,int r)
{
if(l>r) return;//空子树
cout<<root[l][r]<<' ';
print(l,root[l][r]-1);//前序遍历左子树
print(root[l][r]+1,r); //前序遍历右子树
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j++)
f[i][j]=-1;
for(int i=1;i<=n;i++)
{
cin>>f[i][i];//读顶点i的值
root[i][i]=i;//顶点i单独成一棵子树
}
cout<<search(1,n)<<endl;
print(1,n);
return 0;
}