#牛客春招刷题训练营# + 链接
区间dp经典题啦
先套路复制一遍解环,然后用dp[i][j]表示第i颗到第j颗聚合完之后的最优值,每次枚举最后是哪两段聚合就可以
#include <iostream>
using namespace std;
using ll = long long;
const int mod=1e9+7;
const int N=210;
ll dp[N][N], a[N];
inline void getmax(ll &x, ll y)
{
if (y>x) x=y;
}
int main() {
int n,m;
scanf("%d", &n);
for (int i=1;i<=n;i++) {
scanf("%lld", &a[i]);
a[n+i]=a[i];
}
m = n+n;
a[m+1]=a[1];
a[m+2]=a[2];
for (int i=1;i<=m;i++) dp[i][i+1]=a[i]*a[i+1]*a[i+2];
for (int x=3;x<=n;x++) {
for (int i=1,j=x;j<=m;i++,j++) {
for (int k=i;k<j;k++) {
getmax(dp[i][j], dp[i][k]+dp[k+1][j]+a[i]*a[j+1]*a[k+1]);
}
}
}
ll ans = 0;
for (int i=1;i<=n;i++) {
getmax(ans, dp[i][i+n-1]);
}
printf("%lld\n", ans%mod);
return 0;
}



京公网安备 11010502036488号