思路和石头合并基本一致,唯一差别是代价不再是区间和,而是w[i] * w[k+1] * w[j+1]。
以样例为例,将项链长度翻倍拆成链
(2, 3) (3, 5) (5, 10) (10, 2) (2, 3) (3, 5) (5, 10)
2 3 5 10 2 3 5 10
由于每个珠子有俩数字,因此这边翻倍不再是2 * N - 1,而是2 * N。
#include <iostream>
#include <cstring>
using namespace std;
int n, w[205], f[205][205];
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i ++ ) {
scanf("%d", &w[i]);
w[i + n] = w[i];
}
for (int l = 2; l <= n; l ++ ) {
for (int i = 1; i + l - 1 < 2 * n; i ++ ) {
int j = i + l - 1;
for (int k = i; k < j; k ++ ) {
f[i][j] = max(f[i][j], f[i][k] + f[k + 1][j] + w[i] * w[k + 1] * w[j + 1]);
}
}
}
int max_ans = -0x3f3f3f3f;
for (int i = 1; i <= n; i ++ ) {
max_ans = max(max_ans, f[i][i + n - 1]);
}
printf("%d\n", max_ans);
return 0;
}