题目描述
输入格式
诸如此类不能线性规划的问题要用到区间DP,区间DP一般就是三层循环,第一层表示区间长度(本题即n),第二层枚举起点并根据第一层区间长度算出区间终点,第三层便在当前区间内枚举决策(即哪两个合并)
本题由于是环,还需破环为列,可以开两倍大的数组,即a[i]=a[i+n],便可在第n颗珠子时求到第1颗珠子的头标记(也即第n颗珠子的尾标记)
合并珠子即合并左珠dp[i][k]和右珠dp[k+1][j],释放能量a[i]∗a[k+1]∗a[j+1](注意a[i]存放的是第i颗珠子的头标记,所以a[k+1]才是第k个珠子的尾标记)
#include<bits/stdc++.h>
using namespace std;
const int N=222;
using namespace std;
int n,a[N],dp[N][N],ans;
int main() {
cin>>n;
for(int i=1; i<=n; i++)
cin>>a[i],a[i+n]=a[i];
for(int len=2; len<=n; len++)//枚举区间长度
for(int i=1; i+len-1<n*2; i++) {//枚举区间起点
int j=i+len-1;
for(int k=i; k<j; k++)//枚举决策
dp[i][j]=max(dp[i][j], dp[i][k]+dp[k+1][j]+a[i]*a[k+1]*a[j+1]);
}
for(int i=1; i<=n; i++)//枚举可能的答案
ans=max(dp[i][i+n-1],ans);
cout<<ans<<endl;
return 0;
}