4456: 【入门】合并石子(2057)
内存限制:128 MB
时间限制:1.000 S
评测方式:文本比较
命题人:
提交:3
解决:3
题目描述
在一个操场上一排地摆放着 堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的 堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。
设计一个程序,计算出将 堆石子合并成一堆的最小得分。
输入
第一行为一个正整数 ()。
以下 行,每行一个正整数,小于 ,分别表示第 堆石子的个数()。
输出
为一个正整数,即最小得分。
样例输入 复制
7
13
7
8
16
21
4
18
样例输出 复制
239
提示
#include<bits/stdc++.h>
using namespace std;
/*
1.每次只能选相邻的2 堆石子合并成新的一堆
2.并将新的一堆石子数记为该次合并的得分
3.求将N堆石子合并成一堆的最小得分米
*/
const int N= 110;
int f[N][N]; //表示[l,r]合并区间内的数对应的最小得分
int s[N]; //表示前级和
int n;
int main(){
cin>>n;
//边界条件
memset(f,0x3f,sizeof(f)); //默认初始化为无穷大
for(int i= 1;i<= n;i++){
cin>>s[i];
s[i]+= s[i-1]; //求出前缀和
f[i][i]=0; //合并自己的默认得分为0
}
//穷举所有可能的长度
for(int len=2;len<=n;len++){ //穷举区间可能的出发点
for(int l=1;l+len-1<= n;l++){
int r=l+len-1; //区间的终点
//穷举分割点
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]);
}
}
}
cout<<f[1][n];
return 0;
}