石子合并的GarsiaWachs算法

2010-07-28 18:55:51|  分类: 程序 |字号 订阅

石子合并(每次合并相邻的两堆石子,代价为这两堆石子的重量和,把一排石子合并为一堆,求最小代价)

是一个经典的问题。dp可以做到O(n*n)的时间复杂度,方法是:
设f[i,j]为合并从i到j的石子所用最小代价。
f[i,j]=min(sum(i,j)+f[i,k]+f[k+1,j])对所有i<=k<j,其中sum(i,j)表示从i到j的石子重量之和。
设上式取等时k的值为w[i,j],有神牛证明过:w[i,j]>=w[i,j-1],w[i,j]<=w[i+1,j]
这样,枚举k的时候,就有了一个上下界,从而搞掉了一维。
而GarsiaWachs算法可以把时间复杂度压缩到O(nlogn)。
具体的算法及证明可以参见《The Art of Computer Programming》第3卷6.2.2节Algorithm G和Lemma W,Lemma X,Lemma Y,Lemma Z。
只能说一个概要吧:
设一个序列是A[0..n-1],每次寻找最小的一个 满足A[k-1]<=A[k+1]的k,(方便起见设A[-1]和A[n]等于正无穷大)
那么我们就把A[k]与A[k-1]合并,之后找最大的一个满足A[j]>A[k]+A[k-1]的j,把合并后的值A[k]+A[k-1]插入A[j]的后面。
有定理保证,如此操作后问题的答案不会改变。
举个例子:
186 64 35 32 103
因为35<103,所以最小的k是3,我们先把35和32删除,得到他们的和67,并向前寻找一个第一个超过67的数,把67插入到他后面
186 64(k=3,A[3]与A[2]都被删除了)  103
186 67(遇到了从右向左第一个比67大的数,我们把67插入到他后面) 64 103
186 67 64 103 (有定理保证这个序列的答案加上67就等于原序列的答案)
现在由5个数变为4个数了,继续!
186 (k=2,67和64被删除了)103
186 131(就插入在这里) 103
186 131 103
现在k=2(别忘了, 设A[-1]和A[n]等于正无穷大)
234 186
420
最后的答案呢?就是各次合并的重量之和呗。420+234+131+67=852,哈哈,算对了。
证明嘛,基本思想是通过树的最优性得到一个节点间深度的约束,之后
证明操作一次之后的解可以和原来的解一一对应,并保证节点移动之后他所在的
深度不会改变。详见TAOCP。

具体实现这个算法需要一点技巧,精髓在于不停快速寻找最小的k,即维护一个“2-递减序列”
朴素的实现的时间复杂度是O(n*n),但可以用一个平衡树来优化(好熟悉的优化方法),使得最终复杂度为O(nlogn)
事情并没有结束。
我在poj1738上看到了一个50000个数的石子合并,很痛苦地想:要写平衡树了:(
但是当我把朴素实现的代码
http://cid-354ed8646264d3c4.office.live.com/self.aspx/.Public/1738.cpp
交上去的时候,发现,AC了?!
为什么?
平方的复杂度,50000的数据......
我着手分析。
首先,每次combine()(见源代码)操作的时候,并不一定都会访问到整个数组。
从随机的角度来讲,新合并出来的石子堆相比那些已经合并许许多多次的石子堆来说,
并不是很“牛”。因为他并不很牛,所以j的值也不比k小得了多少。
并且我们维护的“2-递减”序列本身就有一个很强的序的关系,所以从某种感觉上讲,combine()递归调用的次数很少。
这只是一个感性的想法,实际上,它唯一能够提供给我们的想法是:隐藏在O(n*n)里的常数非常小!
有多小?自己测试一下,(我的笔记本比较慢)大约实际时间=0.00000036*n*n毫秒
但即使这样,按照多组数据的时间换算一下,还是应该超时的呀。
看题目最后一句话:
For each test case output the answer on a single line.You may assume the answer will not exceed 1000000000.
这句话等价于:每个数都不会很大(要合并49999次呢!),继续等价于:有好多数是相同的。
即使这样,又有什么不同呢?
当然了!
我绘制了一幅平均每次k-j的值关于n的图像

其中橘红色的列是我生成的随机的实数作为数据测的结果,而蓝色的是随机生成的[1,1024]间的整数测得的结果。

很明显,小范围的数据大大“加速”了算法,甚至可能引起复杂度上的差异。
就是这样,让本该写一个平衡树的题用数组AC了。
呵呵。

转自网易博客:http://fanhq666.blog.163.com/blog/static/81943426201062865551410/

石子合并的GarsiaWachs算法相关推荐

  1. 石子合并问题java,石子合并问题 GarsiaWachs算法

    石子合并问题 GarsiaWachs算法 目录引入 一个较为朴素的算法 GarsiaWachs算法 引入 在一个操场上摆放着一排 \(N\) 堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的 ...

  2. 【BZOJ 3229】 3229: [Sdoi2008]石子合并 (GarsiaWachs算法)

    3229: [Sdoi2008]石子合并 Description 在一个操场上摆放着一排N堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合 ...

  3. 石子合并(GarsiaWachs算法)

    对于石子合并问题,有一个最好的算法,那就是GarsiaWachs算法.时间复杂度为O(n^2). 它的步骤如下: 设序列是stone[],从左往右,找一个满足stone[k-1] <= ston ...

  4. GarsiaWachs算法:石子归并问题

    1023 石子归并 V3 基准时间限制:2 秒 空间限制:131072 KB 分值: 320 难度:7级算法题  收藏  关注 N堆石子摆成一条线.现要将石子有次序地合并成一堆.规定每次只能选相邻的2 ...

  5. 【题解】poj1738石子合并 区间DP 加西亚瓦克斯算法

    题目链接 乍一看很激动(诶辣鸡题才做过)然后n=4e4+o(n^3)=GG GarsiaWachs算法 或者四边形优化(还是GG不用搞了)(以后自己写一遍) 还可以加上个平衡树(憋说了--) step ...

  6. 问题描述: 在一个圆形操场的四周摆放着n 堆石子。现要将石子有次序地合并成一堆。 规定每次只能选相邻的2 堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。 试设计一个算法,计算出将n堆石子

    问题描述: 在一个圆形操场的四周摆放着n 堆石子.现要将石子有次序地合并成一堆. 规定每次只能选相邻的2 堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分. 试设计一个算法,计算出将n堆石子 ...

  7. 算法设计与分析——动态规划——石子合并问题

    1.石子合并问题 在一个圆形操场的四周摆放着n堆石子.现要将石子有序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分.设计一个算法,计算出将n堆石子合并成 ...

  8. 算法基础课-动态规划-区间dp-AcWing 282. 石子合并:区间dp

    文章目录 题目分析 题目链接 题目分析 只能合并相邻两堆.求体力最小值 数据比较弱,最多300堆,每堆重量不超过1000. 状态表示 f[i][j]表示合并区间[i,j]需要的最小体力 状态转移 把区 ...

  9. NYOJ 737---石子归并(GarsiaWachs算法)

    原题链接 描述    有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆.求 ...

最新文章

  1. 拼手速抢红包!送大家现金红包!
  2. 数据蒋堂 | 倍增分段技术
  3. 如果不知道MySQL当前使用配置文件(my.cnf)的路径的解决方法
  4. dice系数什么意思_轮胎上的数字和字母是什么意思 轮胎上的红点黄点是什么意思...
  5. Shell通过过滤条件(比如IP)分类流量包,最后合并流量包
  6. 简单的RPC java实现
  7. matlab在电气信息类专业中的应用,MATLAB在电气信息类专业中的应用(高等学校应用型特色规划...
  8. 为什么不使用ipv6计算机网络,ipv6无网络访问权限解决教程
  9. 易飞erp postgre mysql_pgadmin 执行sql
  10. 松翰单片机 c语言例程 宏定义出错,求助.松翰单片机 2714 用仿真器可以 , 但是烧到单片机不行. (amobbs.com 阿莫电子论坛)...
  11. 苹果MAC电脑双系统教程——MAC安装Windows双系统教程
  12. 基于影像基因的肺结节分割、肺癌分类分期、CT影像预测基因突变 --董云云 论文阅读
  13. 微信公众号文章采集 爬取微信文章 采集公众号的阅读数和点赞数?
  14. 分布式存储系统——HBase
  15. 【嵌入式05】Ubuntu下opencv新手操作:(打开图片及视频)
  16. 攻防世界reverse高手进阶 ----- gametime
  17. 视频号主页,实现一键添加个人微信功能,留客更方便,真香
  18. Remote Desktop Connection Manager2.92 安装+基本使用
  19. kindeditor富文本编辑器的使用
  20. String类的intern

热门文章

  1. NewStarCTF 公开赛赛道week3 web writeup
  2. python爬取考研成绩什么时候出来_Python 爬取揭秘,你的考研调剂对手就有谁?...
  3. powerbi输入数据_PowerBI数据编辑与管理
  4. MATLAB sin和sind的区别
  5. Inno Setup 系列之卸载删除文件
  6. 数据链路层----交换机原理
  7. WebGL实时视频(4) js代码交互
  8. 链接脚本.lds文件分析
  9. 为何说美团打车更像是一场破坏行业生态的闹剧?
  10. combobox qt 设置不可更改_[WPF] 实现根据ComboBox选项设定其他控件使能(Enable\Disable)状态...