O興~
 
« 上一篇: 复习一下坐标转换 下一篇: 红黑树(附代码) »
我很懒的 @ 2006-02-09 01:20

这是一个经典的动态规划问题(但厉害的是其中带有一个很神奇的定理),问题是这样的:已知二叉搜索树中每个节点的访问概率,问这棵树整体的搜索时间最短是多少(此时称为最优二叉搜索树)。

众所周知,在二叉搜树中,一次搜索的时间等于待访问节点的深度。所以整体的搜索时间为:



所以如果要整体搜索时间最短,则访问概率高的节点应该比较靠近根节点。乍一听,好像是哈夫曼编码。但是不同的是,这是二叉搜索树,所有节点的左右顺序(这里指中序遍历的顺序)不能变化。所以无法像哈夫曼编码那样一味地把概率高的节点往上移(那是一个贪心算法)。

那该怎么办呢?其实我们只要想到这样一个递推关系:一棵树如果是最优二叉搜索树,那么要么它是空树,要么它的左、右子树也是最优二叉搜索树。这样就得到了动态规划的解法:

For size = 1到n
    For 所有包含size个元素的子树
        For 该子树的所有节点i
            找出其中一个i,使当它为根节点时,左、右子树的最短搜索时间之和最小。那么该子树的访问时间就是:
            左、右子树的最短搜索时间之和 + 所有节点的访问概率之和(因为所有节点都下降了一层)。

可见,这个算法的时间复杂度是O(n^3)。但是有一个神奇的定理,可以把算法的时间效复杂度降到O(n^2),如下:

设一个子树的节点为i ~ j(当然,这里说的i ~ j都是从小到大排好序的),则当它是最优二叉搜索树时的根节点root(i, j)满足:
root(i, j - 1) <= root(i, j) <= root(i + 1, j)。(至于这个定理是如何得来的,很深奥唉,我也不了解。但是一定要会用。)


这样一来,上面那个算法的第3个For就可以不用循环子树中的所有节点了,只要循环另两个子树的根节点之间的范围就可以了。而这个范围根据实践表明是很小的。所以整体的时间复杂度就相当于两层For循环而已。

可以利用这个算法来解决UVA#10304,原题在http://online-judge.uva.es/p/v103/10304.html





评论 / 个人网页 / 扔小纸条
* 昵称

已经注册过? 请登录

新用户请先注册 以便能显示头像及追踪评论回复

Email
网址
* 评论
表情
 


 

分类小组论坛
杂谈 , 娱乐、八卦 , 文学、艺术 , 体育 , 旅游、同城 , 象牙塔 , 情感 , 时尚、生活 , 星座 , 科技

请注意遵守中华人民共和国法律法规, 如威胁到本站生存, 将依法向有关部门报告, 同时本站的相关记录可能成为对您不利的证据.

相关法律法规
全国人大常委会关于维护互联网安全的决定
中华人民共和国计算机信息系统安全保护条例
中华人民共和国计算机信息网络国际联网管理暂行规定
计算机信息网络国际联网安全保护管理办法
计算机信息系统国际联网保密管理规定

日历
网志分类
· 所有网志
· program
· 未分类
站内搜索
友情链接
· 歪酷博客
· 管理我的Blog
· jamie
· feemi
· lyrist
· tata
· allen
· richard

订阅 RSS

0081343

歪酷博客