代码:
#include<bits/stdc++.h> using namespace std; const int N=105; int n; int w[N<<1]; int f[N<<1][N<<1]; int main(){ cin>>n; for(int i=1;i<=n;i++){ cin>>w[i]; w[n+i]=w[i]; } for(int len=3;len<=n+1;len++) for(int l=1;l+len-1<=2*n;l++){ int r=l+len-1; for(int k=l+1;k<=r-1;k++) f[l][r]=max(f[l][r],f[l][k]+f[k][r]+w[l]*w[k]*w[r]); } int res=0; for(int i=1;i<=n;i++) res=max(res,f[i][i+n]); cout<<res<<endl; return 0; }记忆化搜索版本:
#include<bits/stdc++.h> using namespace std; const int N=210; int n; int w[N]; int f[N][N]; int dp(int l,int r){ if(f[l][r]>=0) return f[l][r]; if(r==l || r==l+1) return f[l][r]=0; int &v=f[l][r]; for(int k=l+1;k<=r-1;k++){ v=max(v,dp(l,k)+dp(k,r)+w[l]*w[k]*w[r]); } return v; } int main(){ cin>>n; for(int i=1;i<=n;i++){ cin>>w[i]; w[n+i]=w[i]; } memset(f,-1,sizeof f); int res=0; for(int i=1;i<=n;i++) res=max(res,dp(i,i+n)); cout<<res<<endl; return 0; } 加分二叉树:https://www.acwing.com/problem/content/481/分析
g[l][r] 表示 \([l,r]\) 的根节点。
将中序遍历的序列看作是区间求解,然后枚举根节点(将它作为断点),记录答案的过程中要注意当答案得到更新的时候才记录这个区间的根节点。