1.题目
题目链接:点这儿!
2.解决方法
区间DP是有固定模板的DP类型,它解决的问题都有合并区间(或理解为序列元素)求最优耗费这种模式,而且往往给定的是一个序列,像一个链条一样。但是如果链条的首尾串起来,变成环,该怎么运用区间DP的套路?可以将给定序列复制一倍放在序列的后面,这样做来模拟在环上操作。这样我们得到的最优解需要从通过状态转移方程计算出的f(1,n),f(2,n+1),…,f(i,n+i-1)中寻找。
3.代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int MAXN=110;
int n,s[2*MAXN];
int f[2*MAXN][2*MAXN];
int main(void)
{
cin>>n;
//环拆为链:复制链的一倍到链的后面,模拟环
for(int i=1;i<=n;i++){
cin>>s[i];
s[n+i]=s[i];//复制到(n+1,2n)空间中
}
for(int len=2;len<=n;len++)//区间DP模板
for(int l=1;l+len-1<=2*n;l++){
int r=l+len-1;
for(int k=l;k<r;k++)
f[l][r]=max(f[l][r],f[l][k]+f[k+1][r]+s[l]*s[k+1]*s[r+1]);
}
int ans=0;
for(int i=1;i<=n;i++)//选取f(1,n),f(2,n+1),...,f(i,n+i-1)中的最大值
ans=max(ans,f[i][n+i-1]);
cout<<ans<<endl;
return 0;
}