鹤壁网站推广公司,浏览器加速器,网站后台更新后前台没有同步更新,衡东网络推广公司题目
设有 N 堆石子排成一排#xff0c;其编号为 1,2,3,…,N。
每堆石子有一定的质量#xff0c;可以用一个整数来描述#xff0c;现在要将这 N 堆石子合并成为一堆。
每次只能合并相邻的两堆#xff0c;合并的代价为这两堆石子的质量之和#xff0c;合并后与这两堆石子…题目
设有 N 堆石子排成一排其编号为 1,2,3,…,N。
每堆石子有一定的质量可以用一个整数来描述现在要将这 N 堆石子合并成为一堆。
每次只能合并相邻的两堆合并的代价为这两堆石子的质量之和合并后与这两堆石子相邻的石子将和新堆相邻合并时由于选择的顺序不同合并的总代价也不相同。
例如有 4 堆石子分别为 1 3 5 2 我们可以先合并 1、2 堆代价为 4得到 4 5 2 又合并 1、2 堆代价为 9得到 9 2 再合并得到 11总代价为 491124
如果第二步是先合并 2、3 堆则代价为 7得到 4 7最后一次合并代价为 11总代价为 471122。
问题是找出一种合理的方法使总的代价最小输出最小代价。
输入格式
第一行一个数 N 表示石子的堆数 N。
第二行 N 个数表示每堆石子的质量(均不超过 1000)。
输出格式
输出一个整数表示最小代价。
数据范围
1 ≤ N ≤ 300
思路
我们得到 n 堆石子将石子两两合并。
最外层循环 合并长度为len的区间从len 2开始
中间循环 求出 L 与 R的值长度为len的集合的左右边界
最内层循环 求出f [ l ] [ r ] 的最小值f [ i ][ j ]中储存 i 到 j 区间合并的最小值
代码
#includebits/stdc.h
using namespace std;
const int N 310;
int n;
int s[N];// 前i堆石子的前缀和
int f[N][N];// 表示i到j这个区间合并的最小花费int main()
{cin n;for(int i 1; i n; i ) cin s[i];// 输入每堆石子的个数for(int i 1; i n; i ) s[i] s[i - 1];// 求出前i堆石子的前缀和for(int len 2; len n; len )// 合并长度为len的区间for(int i 1; i len - 1 n; i )// 求出所有长度为len集合合并的最小代价{int l i,r i len - 1;// lr分别为左右边界f[l][r] 0x3f3f3f3f;// 给f[l][r]赋初始值for(int k l; k r; k )// k表示靠近l的区间的长度求f[l][r]这个区间合并的最少花费f[l][r] min(f[l][r],f[l][k] f[k 1][r] s[r] - s[l - 1]);}cout f[1][n] endl;return 0;
}