zoukankan      html  css  js  c++  java
  • poj 3783 Balls 动态规划 100层楼投鸡蛋问题

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4098409.html

    题目链接:poj 3783 Balls 动态规划 100层楼投鸡蛋问题

    使用动态规划算法,使用$dp[i][j]$表示对于i层楼并拥有$j$个鸡蛋时能够判断鸡蛋质量需要的最少次数。
    假如我们在第$k$层扔下一个鸡蛋,则有两种情况,如果鸡蛋没有损坏则问题相当于我们对于$i-k$层楼拥有$j$个鸡蛋所需的最少的次数。
    如果鸡蛋损坏了,则问题相当于对于k层楼拥有$j-1$个鸡蛋的最小次数。从而可以得到动态规划公式:

    egin{equation}
    dp[i][j] = Min(Max(dp[k][j-1],dp[i-k][j])),kin[1,i)
    end{equation}

    数学方法推倒:

    如果我们有$2$个鸡蛋,$k$次投掷机会,那么第一次在$k$层投掷,如果坏掉,则从第一层往上投。
    否则剩下$k-1$次机会,所以要在$k+(k-1)$层投掷,如此往复,两个腕带可以投掷的最高楼层为:

    egin{equation}
    sum_{i=1}^k i = frac{k(k+1)}{2}
    end{equation}

    对于三个鸡蛋k次机会,根据上面的结论,两个鸡蛋$k-1$次可以测试$k(k-1)/2$层楼,所以第一次在$k(k-1)/2+1$层投,如果坏掉,则从第一层往上投。
    否则剩下k-1次机会和两个鸡蛋,则在此基础上增加$(k-1)(k-2)/2+1$层投掷,如此往复。三个鸡蛋可以投掷的最高层为:

    egin{equation}
    sum_{i=1}^k frac{i(i-1)}{2}+1 = frac{k^3+5k}{6}
    end{equation}

    代码如下:

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <iostream>
     4 #include <cstring>
     5 #include  <limits.h>
     6 #define     MAX_F 1001
     7 #define     MAX_E 100
     8 using namespace std;
     9 int dp[MAX_F][MAX_E];
    10 int solve(int floor, int egg)
    11 {
    12     memset(dp, 0, sizeof(dp));
    13     for( int i = 1 ; i <= floor ; i++ )
    14     {
    15         dp[i][1] = i-1;
    16     }
    17     for( int i = 1 ; i <= egg  ; i++ )
    18     {
    19         dp[1][i] = 0;
    20     }
    21     for( int i = 2 ; i <= floor ; i++ )
    22     {
    23         for( int j = 2 ; j <= egg ; j++ )
    24         {
    25             int tmp = INT_MAX;
    26             for( int k = 1 ; k < i ; k++ )
    27             {
    28                 tmp = min(tmp, max(dp[k][j-1] , dp[i-k][j]));
    29             }
    30             dp[i][j] = tmp+1;
    31         }
    32     }
    33     return dp[floor][egg];
    34 }
    35 int main(int argc, char *argv[])
    36 {
    37     int t;
    38     scanf("%d", &t);
    39     while( t-- )
    40     {
    41         int n, egg, floor;
    42         scanf("%d%d%d", &n, &egg, &floor);
    43         printf("%d %d
    ",n, solve(floor, egg));
    44     }
    45 }
    View Code
  • 相关阅读:
    【HDOJ1534】【差分约束+SPFA】
    【HDOJ3861】【Tarjan缩点+最小路径覆盖】
    【二分图最大权完美匹配】【KM算法】【转】
    学习一点汇编 INT 16H指令
    POJ2449 Remmarguts' Date 第K短路
    POJ3090 巧用欧拉函数 phi(x)
    POJ3420 递推+矩阵快速幂
    UVALive 4671 K-neighbor substrings 巧用FFT
    Tyvj 1068 巧用扩展KMP
    第四周 Leetcode 124. Binary Tree Maximum Path Sum (HARD)
  • 原文地址:https://www.cnblogs.com/jostree/p/4098409.html
Copyright © 2011-2022 走看看