一道算法作业题(续)

Description

在一个圆形操场的四周摆放着n堆石子,现要将石子有次序地合并成一堆。规定每次只能选择相邻的两堆石子合并成新的一堆,并将新一堆石子数记为该次合并的得分。试设计一个动态规划算法,计算出将n堆石子合并成一堆的最小得分和最大得分,要求列出递归方程,写出算法的伪代码并分析算法的时间空间复杂性。

分析

要求每次合并必须是相邻的,和矩阵链乘的括号作用差不多。可以考虑往矩阵链乘最小代价的递归方程上靠。设dp[i,j]为第i堆到第j堆合并的最优解,则\(dp[i,j] = min\{dp[i,k]+dp[k+1,j]+v_i+...v_j\}\)

注意由于是圆形,而矩阵链乘是线性的,所以这个递归方程势必需要修改。考虑如何表示环,一个自然的想法是利用mod函数。递归方程修改如下,为了方便表示修改dp[i,j]定义如下:从第i堆开始合并j堆的最优解。(否则需要填写的项数不全在一个矩阵半角上)

\(dp[i,j] = min\{dp[i,k]+dp[(i+k)\%n, j-k]+v_i+...+v_j\}~~~~ i<=k<=j\)

\(dp[i,j] = max\{dp[i,k]+dp[(i+k)\%n, j-k]+v_i+...+v_j\}~~~~ i<=k<=j\)

一点思考

总觉得和之前那道折木棒的很像,画个解的树表示看看,发现几乎一致,同样是求树的所有内部节点的值的和。但是不同的是,对叶节点有限制,即从左到右需要严格按照\(v_1, v_2, ..., v_n\) 排列。那么同样可以利用哈夫曼树的思想解决。维护一个叶节点的数组,每次选择相邻中最小最大的一组\((v_i, v_j)\),生成一个子树,同时将\(v_i,v_j\)删去,新的叶节点\(v_i+v_j\)放入原来\(v_i\)位置。同样可解问题。




直觉两者应该是一个系列的题,去Bing一下。果不其然:

https://blog.csdn.net/acdreamers/article/details/18039073

转载于:https://www.cnblogs.com/KarlZhang/p/9181983.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值