zoukankan      html  css  js  c++  java
  • 算法(动态规划二)

    问题
    腾讯大厦有39层,你手里有两颗一抹一眼的玻璃珠。当你拿着玻璃珠在某一层往下扔的时候,一定会有两个结果,玻璃珠碎了或者没碎。大厦有个临界楼层。低于它的楼层,往下扔玻璃珠,玻璃珠不会碎,等于或高于它的楼层,扔下玻璃珠,玻璃珠一定会碎。玻璃珠碎了就不能再扔。现在让你设计一种方式,使得在该方式下,最坏的情况扔的次数比其他任何方式最坏的次数都少。也就是设计一种最有效的方式。

    分析
    咱们先不论腾讯大厦具体为多少层。假设大楼为 N 层,那么 F(N) 为 N 层大厦最坏情况的最小值。

    先假设一下,在第 10 层进行了抛球:

    碎了,那么寻找临界楼层,最坏情况下只需要从 1 - 9 逐一遍历,也就是 10 次。
    没碎,那么寻找临界楼层,相当于转换为 F(N - 10) + 1 。其中 1 为本次。
    也就是说,第 10 层的最坏情况为 max(10, F(N - 10) + 1)。

    那么 F(N) = min{ max(1, F(N - 1) + 1), max(2, F(N - 2) + 1), max(3, F(N - 3) + 1), …… , max(N - 1, F(1) + 1)}

    有了以上这个状态转移方程,就可以采用动态规划将其实现。

    <?php
         $height = 39;
         echo getMinTimes($height);
    
         function getMinTimes($value)
         {
             $minTimes = []; 
             $minTimes[0] = 0;  // 如果只有0层的话最大次数为0
             $minTimes[1] = 1;  // 如果只有1层的话最大次数为1
             // 初始化参数
             for($levelOne = 2; $levelOne <= $value; $levelOne ++) {
                 $min = $levelOne;
                 for($levelTwo = 1; $levelTwo < $levelOne; $levelTwo ++) {
                     $tmp = max($levelTwo, $minTimes[$levelOne - $levelTwo] + 1);
                     // echo $tmp;
                     // echo "  ";
                     if ($tmp < $min) {
                        $min = $tmp;
                     }
                     // echo $min;
                     // echo "===   ";
                 }
                 // echo PHP_EOL;
                 $minTimes[$levelOne] = $min;
                 // echo $minTimes[$levelOne];
             }
             return $minTimes[$value];
         }
    ?>         
  • 相关阅读:
    HotSpot 的垃圾收集器
    HTML5之日历控件
    设计模式之抽象工厂模式
    设计模式之工厂模式
    设计模式之单例模式
    JavaScript实现input输入框限制输入值的功能
    微信公众号二维码获取
    mybatis的一对多,多对一,以及多对对的配置和使用
    kindeditor在Java项目中的应用以及图片上传配置
    Spring和quartz整合的入门使用教程
  • 原文地址:https://www.cnblogs.com/cjjjj/p/12443709.html
Copyright © 2011-2022 走看看