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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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;
}