区间 dp 石头合并

输入样例
4
1 3 5 2
输出样例
22
(区间 dp)

集合表示最后一次合并选区间中的哪个点作为分界点
状态转义方程 f[l][r] = min(f[l][r], f[l][k] + f[k+1][r] + s[r] - s[l - 1])
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 310;
int n;
int s[N];
int f[N][N];
int main(){
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%d", &s[i]);
// 初始化前缀和
for(int i = 1; i <= n; i++) s[i] += s[i-1];
for(int len = 2; len <= n; len++) // 枚举一次合并的堆的个数 因为 将一堆合并成一堆需要的 0
for(int i = 1; i + len - 1 <= n; i++)
{
int l = i, r= i + len - 1; // 区间的左右端点
f[l][r] = 1e8; // 初始化为 无穷大
for(int k = l; k < r; k ++ ) // 枚举一下使用区间中的哪个点作为最后一次合并的分界点
f[l][r] = min(f[l][r], f[l][k] + f[k+1][r] + s[r] - s[l - 1]);
}
printf("%d\n", f[1][n]);
return 0;
}

浙公网安备 33010602011771号