You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

30 lines
1.1 KiB

2 years ago
#include <bits/stdc++.h>
using namespace std;
const int N = 3010;
const int INF = 0x3f3f3f3f;
int n;
int s[N]; // 前缀和
int f[N][N]; // 表示将i到j合并成一堆的方案的集合,属性:最小值
// 石子合并
int main() {
cin >> n;
// 一维前缀和,直接略过了a[i]数组只用了一个s[i]数组保存前缀和
for (int i = 1; i <= n; i++) cin >> s[i], s[i] += s[i - 1];
memset(f, 0x3f, sizeof f); // 预求最小,先设最大
for (int i = 1; i <= n; i++) f[i][i] = 0; // 第i堆与第i堆是不需要合并的代价为0
// 区间DP模板
for (int len = 1; len <= n; len++) // 枚举区间长度
for (int i = 1; i + len - 1 <= n; i++) { // 枚举区间左端点,右端点计算获取,保证右端点不出界
int j = i + len - 1; // 区间的右端点
// 枚举中间点k
for (int k = i; k < j; k++)
f[i][j] = min(f[i][j], f[i][k] + f[k + 1][j] + s[j] - s[i - 1]);
}
cout << f[1][n] << endl;
return 0;
}