石子合并 环形 DP
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>
#define MOD ((int)(1e9) + 7)
#define eps 1e-10
#define maxn 100010
#define INF (int)(1e9)
using namespace std;
typedef long long ll;
int a[210], sum[210], dp[210][210];
int main() {
int n;
while (scanf("%d", &n) != EOF) {
for (int i = 1; i <= n; ++ i) {
scanf("%d", &a[i]);
}
for (int i = n+1; i <= 2*n; ++ i) {
a[i] = a[i-n];
}
sum[0] = 0;
for (int i = 1; i <= 2*n; ++ i) {
sum[i] = sum[i-1] + a[i];
}
memset(dp, 0, sizeof(dp));
for (int len = 2; len <= n; ++ len) {
for (int i = 1; i <= 2*n; ++ i) {
int j = i + len - 1;
if (j > 2*n) {
dp[i][j] = 0;
continue;
}
int tmp = INF;
for (int k = i; k < j; ++ k) {
tmp = min(tmp, dp[i][k]+dp[k+1][j]+sum[i+len-1]-sum[i-1]);
}
dp[i][j] = tmp;
}
}
int res = INF;
for (int i = 1; i <= n; ++ i) {
res = min(res, dp[i][i+n-1]);
}
printf("%d\n", res);
}
}