(C++)石子合并问题:最大/小代价(动态规划,前缀和优化,最详尽代码注释)

写在所有的前面:

本文采用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]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值