题意
设有NN堆沙子排成一排,其编号为。每堆沙子有一定的数量,可以用一个整数来描述,现在要将这NN堆沙子合并成为一堆,每次只能合并相邻的两堆,合并的代价为这两堆沙子的数量之和,合并后与这两堆沙子相邻的沙子将和新堆相邻,合并时由于选择的顺序不同,合并的总代价也不相同问题是:找出一种合理的方法,使总的代价最小。输出最小代价。
思路
区间动态规划。
设为把第ll堆石子和第堆石子合并到一堆的最小代价。我们枚举一个中间点kk,可以得出动态转移方程:
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[301][301], s[301], a[301], n;
int main() {
memset(f, 127 / 3, sizeof(f));
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
s[i] = s[i - 1] + a[i];//前缀和快速求出区间和
f[i][i] = 0;
}
for (int l = n - 1; l >= 1; l--) {
for (int r = l + 1; r <= n; r++)
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", f[1][n]);
}