时间限制: 1.0 Sec 内存限制: 128 MB
题目描述
设有NN堆石子排成一排,其编号为1,2,3,…,N。
每堆石子有一定的质量,可以用一个整数来描述,现在要将这NN堆石子合并成为一堆。每次只能合并相邻的两堆,合并的代价为这两堆石子的质量之和,合并时由于选择的顺序不同,合并的总代价也不相同。
问题是:找出一种合理的方法,使总的代价最小,输出最小代价。
输入
第一行一个数,NN表示石子的堆数。1≤N≤3001≤N≤300
第二行NN个数,表示每堆石子的质量(均不超过10001000)
输出
输出一个整数,表示最小代价。
样例输入1 复制
5 1 3 4 2 5
样例输出1 复制
34
提示
第一步合1 3 ,此时石子为 4 4 2 5,此时代价为1+3=4
第二步合4 4 ,此时石子为 8 2 5,此时代价为4+(4+4)=12
第三步合2 5 ,此时石子为 8 7,此时代价为12+(2+5)=19
第三步合8 7 ,此时石子为 15,此时代价为19+(8+7)=34
这种方案是代价最小的方案
题目链接:余博士教编程_酷哥OJ_酷哥爱编程_酷哥创客AI编程
代码:
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 310;
int n;
int s[N];
int f[N][N];
int main()
{
cin >> 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 ++ )
{
for(int i = 1; i + len - 1 <= n; i ++ )
{
int l = i, r = i + len - 1;
f[l][r] = 1e9;
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;
}