
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int N=210;
//环状DP
ll dp[N][N];
int a[N],n;//开二倍数组
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i]; //初始化
a[n+i]=a[i];//倍增数组 i和1要分清
}
for(int len=2;len<=n;len++)
//区间长度len
//左端点l
//右端点r
{
for(int l=1;l+len-1<2*n;l++)//约束区间起始点
{
int r =l+len-1;
for(int k=l;k<r;k++)//设置断点
{//同所有的情况进行比较
//原来的能量+新产生的能量
dp[l][r]=max(dp[l][r],dp[l][k]+dp[k+1][r]+a[l]*a[k+1]*a[r+1]);
}
}
}
//对每一个点全部截断取最值
ll ans=0;
for(int i=1;i<=n;i++) ans=max(ans,dp[i][i+n-1]);
cout<<ans<<endl;
return 0;
}
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
typedef long long ll;
const int N=110;
int n,a[N<<1];
ll dp[N<<1][N<<1];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++) a[i+n]=a[i];
for(int l=2;l<=n;l++)//区间长度小于3的时候不执行没有意义
for(int i=1;(i+l-1)<=(2*n-1);i++)
{//保证右端点的范围
//i+l-1表示区间的右端点
//2n是复制之后最后一个珠子的索引
//2n-1是因为不用遍历到复制之后的最后一个珠子
//n-2n和1-n没有区别
int j=i+l-1;//定义右端点
for(int k=i;k<j;k++)//断点从左端点开始小于右端点
dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+1ll*a[i]*a[k+1]*a[j+1]);
//dp[i][k]表示合并区间[i,j]能够获得的最大分数
//a[i]是第i-1颗珠子的为
}
//2 3 5 10
/*若
i指向2
k指向3
j指向10
那么1ll*a[i]*a[k+1]*a[j+1]就是2*5*2
此时表示将A(2 3)和B(5 10)进行合并,A合并之后的头为2 尾标记为5 B合并之后头标记为5 尾标记为2(10是最后一颗珠子,首尾相连)
*/
ll ans=0;
for(int i=1;i<=n;i++) ans=max(ans,dp[i][i+n-1]);
printf("%lld\n",ans);
return 0;
}