zoukankan      html  css  js  c++  java
  • uva 10934 Dropping water balloons(转载)

    本文转载自http://blog.csdn.net/shuangde800/article/details/11273123

    题意

    你有k个一模一样的水球,在一个n层楼的建筑物上进行测试,你想知道水球最低从几层楼往下丢可以让水球破掉。由于你很懒,所以你想要丢最少次水球来测出水球刚好破掉的最低楼层。(在最糟情况下,水球在顶楼也不会破)你可以在某一层楼丢下水球来测试,如果水球没破,你可以再捡起来继续用。

    Input

    输入的每一行包含多组测试,每组测试为一行。每组测试包含两个整数 k 和 n, 1 <= k <= 100 而 n 是一个 64 位的整数(没错,这栋建筑物的确很高),最后一组k = 0,n=0 代表结束,这组测试不用处理。

    Output

    对于每次测试,输出在最糟情况下,测出水球破掉楼层的最少次数。如果他多于63次,就输出“More than 63 trials needed.”

    思路

    题目已经说得很清楚了,要在最糟糕的情况下(即最后一层才能摔破,但是你不知道是最后一层),用最少的次数可以知道。

    在假设你有无数个水球的情况下,那么最少的次数肯定就是用二分的方法:首先在正中间摔下去,如果破的话,说明目标位
    置在下半部分,不破的话说明是在上半部分。上后继续在对应的部分再二分下去……需要logn次。

    但是这题的水球数量有限,例如,只有一个水球的情况下,你直接在正中间楼层放下去,如果摔破的话,那么你就没有其它
    球继续做实验了。所以你只能从第一层开始一直往上丢,第一个摔破的楼层就是目标楼层了。那么最糟糕的情况下就是要做N次。

    这样的话还是不太好想,所以要把问题转换一下,变成:“给k个气球,丢j次,最多能确定第几层?”
    这样,就可以用f(i, j)状态来表示第i个气球,丢j次最多确定的层数。

    对于f(i, j), 我们不知道它最多可以确定第几层,假设第一次在x层仍球,如果球破了,那么我们花费了一个球和仍了一次的费用,
    我们可以知道f(i-1, j-1)可以确定的层数,那么就可以确定x = f(i-1, j-1) + 1。
    如果在x层时如果球没有破,那么我们只花费了仍一次的费用,还剩下i个球,j-1次可以用,那么用这些可以确定的层数f(i, j-1)

    所以,得到递推式,推出最高能确定的层数:
    f(i, j) = f(i-1, j-1) + 1 + f(i, j-1);

    代码:

    /*************************************************************************
        > File Name:            4.cpp
        > Author:               Howe_Young
        > Mail:                 1013410795@qq.com
        > Created Time:         2015年08月15日 星期六 16时47分41秒
     ************************************************************************/
    
    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    #include <algorithm>
    
    using namespace std;
    typedef long long ll;
    const int maxn = 110;
    ll dp[maxn][maxn];
    void init()
    {
        memset(dp, 0, sizeof(dp));
        for (int i = 1; i < 64; i++)
            for(int j = 1; j < 64; j++)
                dp[i][j] = dp[i - 1][j - 1] + dp[i][j - 1] + 1;
    }
    void print()
    {
        for (int i = 1; i < 64; i++)
        {
            for (int j = 1; j < 64; j++)
                cout << dp[i][j] << " ";
            cout << endl;
        }
    }
    int main()
    {
        init();
        int k; ll n;
        while (~scanf("%d %lld", &k, &n) && k)
        {
            k = min(63, k);
            bool flag = false;
            for (int i = 1; i < 64; i++)
            {
                if (dp[k][i] >= n)
                {
                    flag = true;
                    printf("%d
    ", i);
                    break;
                }
            }
            if (!flag)
                puts("More than 63 trials needed.");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    47. VUE-路由是什么?如何实现页面不请求刷新?
    21. SpringBoot 实现国际化 [i18n]
    20. SpringBoot 默认访问首页 以及 加载静态资源
    46. VUE 脚手架 —— vue ui 管理 以及 查看原始配置
    45. VUE ClI4 创建项目
    44.VUE2 项目目录结构解析 和 Runtime-Compiler和Runtime-only的区别
    2 . Mybatis — 增-删-改
    19. SpringBoot 扩展 SpringMVC功能、 接管、自定义SpringMVC
    17. Thymeleaf 模板 的 使用 和 语法
    16. SpringBoot 模板引擎
  • 原文地址:https://www.cnblogs.com/Howe-Young/p/4732764.html
Copyright © 2011-2022 走看看