区间动规
dp[i][j]指第i个珠子到第j个珠子可以释放的最大能量
1.两堆合并
dp[i][i+2]=num[i]*num[i+1]*num[i+1]=dp[i][i+1]+dp[i+1][i+2]+num[i]*num[i+1]*num[i+1]
2.三堆合并
dp[i][i+3]=max(dp[i][i+1]+dp[i+1][i+3]+num[i]*num[i+1]*num[i+3],dp[i][i+2]+dp[i+2][i+3]+num[i]*num[i+2]*num[i+3])
3.推广:第i个珠子到第j个珠子的合并
dp[i][i+3]=max(dp[i][k]+dp[k][j]+num[i]*num[k]*num[j])
i<k<j
#include <iostream>
using namespace std;
int dp[101][101], num[101], n, Max;
//dp[i][j]指第i个珠子到第j个珠子可以释放的最大能量
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
cin >> num[i];
for (int len = 2; len <= n; len++) //len是合并珠子的数量
for (int i = 0; i < n; i++) //i是合并珠子的起点,j为合并珠子的终点
{
int j = len + i;
if (j >= n) j -= n;
for (int k = i + 1; k < len + i; k++) //枚举每个分割的位置k
{
int m = k;
if (m >= n) m -= n;
if (dp[i][j] < dp[i][m] + dp[m][j] + num[i] * num[m] * num[j])
dp[i][j] = dp[i][m] + dp[m][j] + num[i] * num[m] * num[j];
}
}
for (int i = 0; i < n; i++)
{
if (Max < dp[i][i]) Max = dp[i][i];
}
cout << Max << endl;
return 0;
}