• 由UVa10934(动态规划)引发的感想


    这道题有很多解法,一开始感觉对这道题十分迷,然后看了其他人的博客,发现很多都是千篇一律,有的直接抄紫书的题解了,

    我是个蒟蒻,看不懂,于是很蒙......然后继续努力在网上找资料,最后我知道这类问题了,这类问题的名字叫做鹰蛋问题,

    通过2004年IOI国家集训队朱晨光的论文学习到了很多。

    有一堆共 M 个鹰蛋,一位教授想研究这些鹰蛋的坚硬度 E。他是通过不断
    从一幢 N 层的楼上向下扔鹰蛋来确定 E 的。当鹰蛋从第 E 层楼及以下楼层落下
    时是不会碎的,但从第(E+1)层楼及以上楼层向下落时会摔碎。如果鹰蛋未摔
    碎,还可以继续使用;但如果鹰蛋全碎了却仍未确定 E,这显然是一个失败的实
    验。教授希望实验是成功的。
    例如:若鹰蛋从第 1 层楼落下即摔碎,E=0;若鹰蛋从第 N 层楼落下仍未碎,
    E=N。
    这里假设所有的鹰蛋都具有相同的坚硬度。给定鹰蛋个数 M 与楼层数 N。
    要求最坏情况下确定 E 所需要的最少次数。
    这道题看似向二分查找但是我们发现对鹰蛋的个数有限制,所以不能简单的使用二分查找来进行求解,
    定义一个状态d(i,j)表示用i个蛋在j层楼最坏的情况下确定E所需要最少的次数
    不难得出d(i,j)=min{max{d(i-1,w-1),d(i-1,j-w)}+1|1<=w<=j}(状态转移方程的推导省略,建议看论文)
    这种方法需要O(n^3)的情况,时间承受不了,还能优化吗?肯定的,这道题类似于二分查找,只不过
    限定了鹰蛋的个数,我们不妨假设鹰蛋的个数无穷大呢?这样我们可以使用二分查找很快的找出答案,
    那么我们知道当M>=log(n+1)时我们直接用二分查找就行了,当M<log(n+1)时我们使用动态规划,这样我们
    减少了状态数量,可以将算法优化到O(n^2logn),还能够优化吗?仍然可以,这次我们对状态转移进行优化
    我们不难发先d(i,j)>d(i,j-1)然后画一个图:
    (如图 2,令①为 f(i-1,w-1)图象,②为 f(i,j-w)图象(皆用线段连结相邻两点), ③即为 max{f(i-1,w-1),f(i,j-w)}+1 的图象)
    发现可以wbest的位置满足于3这条线的形状有特点所以可以对其进行三分(不确定),这样我们状态转移降成了O(logn),总的时间复杂度为O(n(logn)^2)
    还能优化吗?当然可以,不过大家可以去看论文就行了,这里我就不陈述优化的方法了,可以看出动态规划有很多种方法提高效率(状态定义、状态转移方程、
    状态总数、决策数等等),对于UVa10934来说,上面的方法都不能够解决问题,为什么?因为楼房太高了(2^64),超出了内存限制,
    所以我们只能够修改状态的定义了,这在论文中有具体的论述,在这里我就简单说一说了。
    我们定义d(i,j)表示用i个球实验j次所测试的楼的最高层数(这里的最高指的是最多),对于取k层(这里的k是随机取的不会影响状态转移方程),假设碎了,那么硬度E所对应的高度H一定满足H<W,于是我们看d(i-1,j-1)的最高层数(其子问题一定满足最优——最优子问题),如果没有碎,那么我们知道H>=W于是我们
    看d(i-1,j)所能到达的最高层数,最后总的层数为d(i,j)=d(i-1,j-1)+d(i-1,j)+1(看图知道“1”的由来)。

     代码就看lrj的代码仓库吧!

  • 相关阅读:
    Python 入门变量类型标识符和关键字
    对于msSql中exists操作符求值的疑惑
    那个蛋痛的list的remove_if中用到的对像函数
    继承一个虚类的时候要小心是,并使其实例化时.必须使其全实重写了纯虚的方法...类定义的位置
    MSSQL(TSQL)中的varchar不指定大小好像一般来说只有一个的长度
    关于TSQL中触发器的只言片语
    MSSQL十秒一次的job
    用了Rime输入法之后,发现IE要关闭保护模式才能输入
    三性原则,指的是商业银行的“安全性、流动性、效益性
    九选三
  • 原文地址:https://www.cnblogs.com/yifeiWa/p/11294225.html
Copyright © 2020-2023  润新知