加分二叉树
#include <bits/stdc++.h> using namespace std; //加分二叉树 int n,dp[40][40]={0},a[40],ans=0,root[40][40]; void f(int i,int j){ if(i>j) return; cout<<root[i][j]<<" "; f(i,root[i][j]-1); f(root[i][j]+1,j); } int main() { cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; for(int l=1;l<=n;l++){ for(int i=1;i<=n-l+1;i++){ int j=l+i-1; //k有区间的根节点的位置 //事实上,在已有两个点时,怎么左右子树哪一个是空没有区别,答案优先左子树是空 //这么写是因为,在左右子树是空的时候,会有一个dp[i][k-1]、dp[k+1][j]=0,会干扰 if(dp[i+1][j]+a[i]>=dp[i][j-1]+a[j]){ //只有两个点时,dp[i+1][j]+a[i]=dp[i][j-1]+a[j],这是规定选择i为根 dp[i][j]=dp[i+1][j]+a[i]; root[i][j]=i; } else{ dp[i][j]=dp[i][j-1]+a[j]; root[i][j]=j; } //左右都不是空 for(int k=i;k<=j;k++){ if(dp[i][k-1]*dp[k+1][j]+a[k]>dp[i][j]){ dp[i][j]=dp[i][k-1]*dp[k+1][j]+a[k]; root[i][j]=k; } } ans=max(ans,dp[i][j]); } } cout<<ans<<endl; f(1,n); return 0; }