写在所有的前面:
本文采用C++实现代码
目录
题目说明
题目
题目出处
《算法设计与分析》课上随堂测验
题目描述Description
设有 n 堆石子排成一排,其编号为 1,2,3,…,n。
每堆石子有一定的质量,可以用一个整数来描述,现在要将这 n 堆石子合并成为一堆。
每次只能合并相邻的两堆,合并的代价为这两堆石子的质量之和,合并后与这两堆石子相邻的石子将和新堆相邻,合并时由于选择的顺序不同,合并的总代价也不相同。
找出使总代价最小/最大的方法,输出最小/最大代价。
输入Input
第一行:一个整数 n,代表石子堆数
第二行:n 个整数,代表每堆石子质量
输出Output
第一行:一个整数,代表最小价值
第二行:一个整数,代表最大价值
样例Sample
输入:
4
4 4 5 9
输出:
43
54
限制Hint
解答说明
方案1:动态规划
解题思路
类似于矩阵连乘:本人写的《矩阵连乘(动态规划)(C/C++)最详尽代码注释》
https://blog.csdn.net/just_do_it_sq/article/details/142218288?spm=1001.2014.3001.5501
寻找最佳分隔点(最后一个合并的位置)
从连续 2 堆合并开始,不断增大到所有石子合并
从 i 到 j 开始遍历设分隔点 k ,取最优解
用前缀和队列优化多个数值的合并值计算
一般情况
最后分隔点为 k 时,最后一次合并后,合并总值为:左边总代价 + 右边总代价 + 总质量
特殊情况
一堆石子无法合并,mx[i][i] = mn[i][i] = 0
代码实现
#include<iostream>
using namespace std;
const int N = 100;//常量 N
int n;//n堆石子
int a[N]