zoukankan      html  css  js  c++  java
  • [动态规划] 谷歌鸡蛋问题

     

    问题:

    现有2个鸡蛋硬度相同,100层的楼房。鸡蛋从某一层楼房扔下时,可能会破碎。为找出使鸡蛋破碎不破碎的最高楼层f(0<=f<=100),需要做x次实验,求x的最小值。

    扩展问题:

    先有M个鸡蛋,N层楼房,为找出使鸡蛋不破碎的最高楼层,需要做x次实验,求x的最小值。

      


     

    问题分析:

    这个问题刚拿到时,很容易想到用二分法求解,因为看上去很像有序集合的查找。确实,若鸡蛋数量足够多,二份法是最快的求解方式,需要log2100向上取整次。若鸡蛋在f层破碎,则在[1,f-1]区间查找,若不破碎则在[f+1,100]区间内求解。但是,当鸡蛋数量小于二分法所需的数量时,就不能用二份法求解。特别地,当只有一个鸡蛋时,应该从1层向上逐渐测试每一层。

     

    从测试的第一步开始考虑,此时有两个鸡蛋且未做任何实验。第一次在f1层进行实验,可能有两种结果,破碎或不破碎。若鸡蛋在f1层破碎,则剩下的问题是在[1, f1-1]层中查找,且只剩1个鸡蛋;若鸡蛋在f1层不破碎,则剩下的问题是在[f1+1,100]层中查找,且剩下2个鸡蛋。可以看出,子问题有两个影响因素,所剩楼层及所剩鸡蛋。

    定义f(n,m)为有m个鸡蛋,n层楼房,需要的最小实验次数。已知f(0,m) = 0,根据之前的分析又有f(n, 1) = 1。可以写出递归公式。

    f(n,m) = min(i from 1 to n) ( max( f(i-1, m-1), f(n - i - 1, m)) ) + 1

    可以利用动态规划求解。

     

    以15层2个鸡蛋为例求解。

      0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
    1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
    2 0 1 2 2 3 3 3 3 4 4 4 5 5 5 5 5

    利用该递归关系,可以解出100楼2个鸡蛋最少需要14次测试。


    代码示例:

    import sys
    
    g_res_table = []
    
    def Compute(floor, egg):
        global g_res_table
        if floor <= 0 or egg <= 0:
            return -1
        
        # initial result table
        for i in range(0, floor + 1):
            lst_floor = []
            for j in range(0, egg + 1):
                lst_floor.append(0)
            g_res_table.append(lst_floor)    
        
        for i in range(1, egg + 1):
            g_res_table[1][i] = 1
            g_res_table[0][i] = 0
        
        # initial value
        for i in range(0 ,floor + 1):
            g_res_table[i][1] = i
    
        for i in range(2, floor + 1):
            for j in range(2, egg + 1):
                tmp_min = -1
                for cur in range(1, i + 1): 
                    if g_res_table[cur - 1][j - 1] > g_res_table[i - cur][j]:
                        max_value = g_res_table[cur - 1][j - 1]
                    else:   
                        max_value = g_res_table[i - cur][j] 
                    if max_value < tmp_min or tmp_min == -1:
                        tmp_min = max_value
                g_res_table[i][j] = 1 + tmp_min        
    
        return g_res_table[floor][egg]        
    
    def main(): 
        floor = int(sys.argv[1])
        egg = int(sys.argv[2])
        res = Compute(floor, egg)
        print res
    
    if __name__ == '__main__':
        main()

     

     

  • 相关阅读:
    MediaRecorder.AudioSource参数
    putty连接服务器
    支持库
    ImageView
    .net下MD5算法和加盐
    SqlHelper文件复习
    .net下连接数据库
    Windows Server 2003 R2 64位简体中文版下载
    gacutil.exe 注册assembly
    Sharepoint Powershell
  • 原文地址:https://www.cnblogs.com/terencezhou/p/2668360.html
Copyright © 2011-2022 走看看