由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的代码仓库吧!

猜你喜欢

转载自www.cnblogs.com/yifeiWa/p/11294225.html
今日推荐