• 鹰蛋坚硬度实验


    问题大意:给你 n 个鸡蛋,问你在 m 层中,进行多少次投鹰蛋能确定,鹰蛋最高在哪层能不碎( 即最坏情况需要多少次 ),

    如果第m层也不碎答案为m。

    这个问题好像有个大牛写过一篇论文。我只学了其中的两个方法。

    第一种方法是 log( n )*n^2,我们将状态设成 dp[ i ][ j ] 表示成有 i 个鸡蛋,层数为 j 时最少需要的实验次数。

    那么我们考虑在第一次在 k 层投鹰蛋,有两种情况,一种是鹰蛋碎了 这种状况对应的子问题为dp[ i -1 ][ k-1 ](k层下面的部分),

    另一种子问题是鹰蛋没碎为 dp[ i ][ m-k ](k层上面的部分),因为考虑最坏的情况,所以取两者的最大值赋给dp[ i ][ j ],并加上

    第一次在k层投的一次。 对于k是哪个,只需要枚举 k 就可以了。考虑鸡蛋充足的情况,那么就是二分的方法,这样对于

    i > log(j) 的状态直接赋值。

    #include<bits/stdc++.h>
    using namespace std;
    const int inf=0x3f3f3f3f;
    int dp[12][1005],n,m;
    int main()
    {
        //freopen("text2","w",stdout);
        memset(dp,inf,sizeof(dp));
        for(int i=1;i<=1000;i++) dp[1][i]=i;
        for(int i=1;i<=10;i++) dp[i][1]=1;
        for(int i=2;i<=10;i++)
        {
            for(int j=1;j<=1000;j++)
            {
                int res;
                dp[i][j]=dp[i-1][j];//这里特别注意,wa地生活不能自理。
                for(int k=1;k<=j;k++)
                {
                    dp[i][j]=min(dp[i][j],max(dp[i-1][k-1]+1,dp[i][j-k]+1));
                }
            }
        }
        while(scanf("%d%d",&n,&m)!=EOF && n && m)
        {
            if(m==0)
            {
                puts("0");
                continue;
            }
            if(n>10) n=10;
            printf("%d
    ",dp[n][m]);
        }
        return 0;
    }
    View Code

    第二种方法是,我们考虑dp[ i ][ j ]为有 j 个鸡蛋进行 i 次能确定的最高楼层。假设在某一层楼扔下一只蛋,且碎了,

    则在下面的( j - 1)次里,我们要用(i-1)个蛋在下面的层中确定 E为了使 dp(i,j)达到最大,我们当然希望下面的楼层数达到最多,

    这便是一个子问题,答案为 dp[ i - 1 , j - 1 ];假设蛋没碎,则在后面( j - 1)次里,我们要用 i 个蛋在上面的楼层中确定 E,

    这同样需要楼层数达到最多,便为 dp[ i - 1 , j ],然后不管怎样,我们都用了一次。即dp[ i , j ]=dp[ i - 1 , j - 1 ] + dp[ i , j - 1 ] + 1。

    #include<bits/stdc++.h>
    using namespace std;
    LL dp[1010][1010];
    int main()
    {
        for(int i=1;i<=1000;i++)
        {
            dp[1][i]=i;
            dp[i][1]=1;
        }
        for(int i=2;i<=1000;i++)
        {
            for(int j=2;j<=1000; j++)
            {
                dp[i][j]=dp[i][j-1]+dp[i-1][j-1]+1;
            }
        }
        int n,m;
        while(cin>>m>>n, n && m)
        {
            LL ans=-1;
            for(int i=1;i<=1000;i++)
            {
                if(dp[m][i]>=n)
                {
                    ans=i;
                    break;
                }
            }
            cout << ans << endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    堆和栈的区别!
    产品经理和程序员的爱恨情仇
    字符串MD5加密运算
    事件驱动模型。。。。有时间弄
    Apache服务器httpd.exe进程占用cpu超过50%的解决方法
    ZigBee Xbee S2通讯设置
    pipe-filter 真难找啊
    javacomm64位用不了,可以使用RXTXcomm for x64
    导入 sun.net.TelnetInputStream; 报错
    linux下gedit读取txt乱码解决办法
  • 原文地址:https://www.cnblogs.com/CJLHY/p/7347848.html
Copyright © 2020-2023  润新知