动态规划经典题——石子合并

题目信息

路边玩法

有n堆石子放在路边一列,现在要将石子有序地合并成一堆,规定每次只能移动相邻的两堆石子合并,合并花费为新合成的一堆石子的数量。求将这N堆石子合并成一堆的总花费(最小或最大)

操场玩法

一个圆形操场周围摆放着n堆石子圆圈,现在要将石子有序地合并成一堆,规定每次只能移动相邻的两堆石子合并,合并花费为新合成的一堆石子的数量。求将这N堆石子合并成一堆的总花费(最小或最大)

问题分析

路边玩法

如果n-1次合并的全局最优解包含了每一次合并的子问题的最优解,那么经这样的n-1次合并后的花费总和必然是最优的。
在这里插入图片描述

操场玩法

如果把路边玩法看成石子合并问题,那么操场玩法就属于圆形石子合并问题。圆形石子合并经常转换为直线型来求。也就是说,把圆形结构看成是长度为原规模两倍的直线结构来处理,如果操场玩法的规模为n,所以相当于有一排石子 a1, a2, … an, a1, a2, …, an-1,该问题规模为2n-1。最后从规模是n的最优值找出最小值或最大值即可

算法设计

路边玩法

1. 确定合适的数据结构
	采用一维数组 a[i]来记录第i堆石子的数量;
	sum[i]来记录前i堆石子的总数量;
	二维数组Min[i][j]、Max[i][j]来记录第i堆到第j堆石合并的最小和最大花费
2. 初始化
	输入石子的堆数n,然后依次输入各堆石子的数量存储在a[i]中,
	令Min[i][j]=0,Max[i][j]=0,sum[0]=0,计算sum[i].
3.循环阶段
	按照递归式计算2堆石子合并{
   ai, a i+1}的最小和最大花费
	依次类推,直到求出所有堆的最小和最大花费
4.构造最优解
	Min[1][n]和Max[1][n]是n堆石子合并的最小和最大花费。
	如果还想知道具体的合并顺序,需要在求解的过程中记录最优决策,然后逆向构造最优解,
可以使用类似矩阵连乘的构造方法,用括号来表达合并的先后顺序。	

操场玩法

从规模为n的最优值M[1][n],Min[2][n+1],Min[3][n+2],,,Min[n][2n-1]
中找最小值作为圆形石子合并的最小花费。
最大值同理

完美图解(以路边玩法为例)

在这里插入图片描述在这里插入图片描述在这里插入图片描述剩下的可以看趣学算法

伪代码详解

路边玩法

void straight(int a[], int n) {
   
	for (int i = 1; i <= n; i++) {
   //初始化
		Min[i][i] = 0, Max[i][i] = 0;
	}
	sum[0] = 0;
	for (int i = 1; i <= n; i++) {
   
		sum[i] = sum[i - 1] + a[i];
	}
	for (int v = 2; v <= n; v++) {
   //枚举合并的堆数规模
		for (int i = 1; i <= n - v + 1; i++) {
   //枚举起点
			int j = i + v - 1;	//枚举终点j
			Min[i][j] = INF;		//初始化最大值
			Max[i][j] = -1;			//初始化最小值
			int tmp = sum[j] - sum[i - 1];	//记录i...j之间的石子数之和
			for (int k = i; k < j; k++) {
   
				Min[i][j] = min(Min[i][j], Min[i][k] + Min[k + 1][j] + tmp);
				Max[i][j] = max(Max[i][j], Max[i][k] + Max[k + 1][j] + tmp);
			}
		}
	
	}
}

操场玩法


void Circular(int a[], int n) {
   
	for (int i = 1; i <= n-1; i++) {
   
		a[n + i] = a[i
  • 11
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值