#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
const int N = 305;
int dp[N][N];
int a[N];
int s[N];
int n;
int main() {
cin >> n;
memset(dp, 0x7f, sizeof dp);
for (int i = 1; i <= n; i++) {
cin >> a[i];
s[i] = s[i - 1] + a[i]; // 构造前缀和
dp[i][i]=0; // 合并自己代价为0
}
for (int len = 2; len <= n; len++) {
for (int l = 1; l + len - 1 <= n; l++) {
int r = l + len - 1; // 这个要减1
for (int k = l; k < r; k++) {
dp[l][r] = min(dp[l][r], dp[l][k] + dp[k + 1][r]+s[r]-s[l-1]);
}
}
}
cout << dp[1][n];
return 0;
}
再看一个进阶版的
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
int n;
const int N = 205;
int dpmin[N][N];
int dpmax[N][N];
int a[N];
int main() {
cin >> n;
memset(dpmin, 0x7f, sizeof dpmin);
memset(dpmax, -1, sizeof dpmax);
for (int i = 1; i <= n; i++) {
cin >> a[i];
a[i + n] = a[i];
dpmin[i][i] = dpmin[i + n][i + n] = dpmax[i][i] = dpmax[i + n][i + n]=0;
}
int ans1 = -1;
int ans2 = 0x7fffffff;
for (int start = 0; start < 100; start++) {
// start 为偏移量
memset(dpmin, 0x7fffffff, sizeof dpmin);
//for (int i = 0; i < N; i++) {
// for (int j = 0; j < N; j++) {
// dpmin[i][j] = 0x7ffff;
// }
//}
memset(dpmax, -1, sizeof dpmax);
for (int i = 1; i <= 2*n; i++) {
dpmin[i][i] = dpmax[i][i] = 0;
}
for (int len = 2; len <= n; len++) {
for (int l = 1 + start; l <= n + start - len + 1; l++) {
int r = l+len-1;
int cost = 0;
for (int zuo = l; zuo <= r; zuo++) {
cost += a[zuo];
}
for (int k = l; k < r; k++) {
dpmax[l][r] = max(dpmax[l][r], dpmax[l][k] + dpmax[k + 1][r] + cost);
dpmin[l][r] = min(dpmin[l][r], dpmin[l][k] + dpmin[k + 1][r] + cost);
}
}
}
ans1 = max(ans1, dpmax[1 + start][n + start]);
ans2 = min(ans2, dpmin[1 + start][n + start]);
}
cout << ans2 << endl;
cout << ans1 << endl;
}