博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一道算法作业题(续)
阅读量:4681 次
发布时间:2019-06-09

本文共 850 字,大约阅读时间需要 2 分钟。

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://www.cnblogs.com/KarlZhang/p/9181983.html

你可能感兴趣的文章
如何修改TableViewCell中的ImageView的Frame和大小
查看>>
orm框架的学习mybatis
查看>>
第四章 基本数据管理
查看>>
linux命令--chmod
查看>>
daily scrum 11.9
查看>>
2018 CCPC 桂林站(upc复现赛)总结
查看>>
VS文件清理工具--只用于VS--MFC项目
查看>>
增加view的圆角笔记
查看>>
第三次作业--团队展示
查看>>
Windows环境下sublime text 3搭建前端开发环境
查看>>
JS方法用来判断手机是安卓还是ios系统
查看>>
《大道至简》读后感
查看>>
处理某个json文件的代码
查看>>
SQLServer存储过程返回值总结
查看>>
使用Sqlserver事务发布实现数据同步
查看>>
创建一个对象都在内存中做了什么事情
查看>>
使用HTML+CSS,jQuery编写的简易计算器
查看>>
gitlab-ce 安装、汉化与阿里邮箱配置(注意是CE)
查看>>
zabbix3.4 监控ESXI6.7
查看>>
c++继承赋值兼容
查看>>