demon:
#include<iostream>
using namespace std;
int arr[200],n;
int dp[200][200],fdp[200][200];//前小后大顺序,前大后小逆序
int sch(int l,int r){
if(dp[l][r])return dp[l][r];
for(int i=l+1;i<r;i++){
dp[l][r]=max(sch(l,i)+sch(i,r)+arr[l]*arr[i]*arr[r],dp[l][r]);
}
return dp[l][r];
}
int fsch(int l,int r){
if(fdp[l][r])return fdp[l][r];
for(int i=1;i<l;i++){
fdp[l][r]=max(fsch(i,r)+sch(i,l)+arr[l]*arr[i]*arr[r],fdp[l][r]);
}
for(int i=r+1;i<=n;i++){
fdp[l][r]=max(sch(r,i)+fsch(l,i)+arr[l]*arr[i]*arr[r],fdp[l][r]);
}
return fdp[l][r];
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>arr[i];
}
for(int i=1;i<n;i++){
for(int j=i+1;j<=n;j++){
sch(i,j);
}
}
for(int i=1;i<n;i++){
for(int j=i+1;j<=n;j++){
fsch(i,j);
}
}
int res=0;
for(int i=1;i<n;i++){
for(int j=i+1;j<=n;j++){
res=max((max(arr[i],arr[j])*max(arr[i],arr[j])*min(arr[i],arr[j])+dp[i][j]+fdp[i][j]),res);
}
}
cout<<res;
return 0;
}
可以模拟成把这一个一个数往里面插,获得能量
比如 a1 a2中间插入a3:那么能量就是a1*a3*a2
思路:dp[i][j](i<j)表示按顺时针顺序(小于i的和大于j的暂时不管)把ij区间内的珠子都去掉,只剩下ij,可获得的最大值。fdp[i][j](i<j)表示按逆时针把小于i的和大于j的去掉,也就差不多是把dpij剩下的珠子的补集去掉可以获得的最大价值
这时候max(arr[i],arr[j])*max(arr[i],arr[j])*min(arr[i],arr[j])+dp[i][j]+fdp[i][j]就是这俩最后的珠子合并后的答案。
dp想不动了,就记忆深搜吧