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:                 [email protected]
    > 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\n", i);
                break;
            }
        }
        if (!flag)
            puts("More than 63 trials needed.");
    }
    return 0;
}

时间: 2024-10-19 01:35:20

uva 10934 Dropping water balloons(转载)的相关文章

UVa 10934 - Dropping water balloons(DP)

给出n个相同的气球,k层楼,问最少几次试验可以知道气球最高从多少层扔下不会爆. 用d[i][j]表示用i个球,实验j次所能确定的最高楼层数,对于每一次试验分爆和不爆两种情况讨论: 1.爆了,转移到d[i?1][j?1]+1,用掉了1个球和一次试验机会. 2.没爆,将当前测试层数的上一层当做第1层继续进行试验,转移到d[i][j?1]. 得出转移方程d[i][j]=d[i?1][j?1]+1+d[i][j?1]. 好久之前做的题了,具体思路见紫书. #include<cstdio> #inclu

10934 - Dropping water balloons(DP)

这道题的思路非常难想. 问你须要的最少实验次数,这是非常难求解的.并且我们知道的条件仅仅有三个.k.n.实验次数 . 所以我们最好还是改变思路,转而求最高所能确定的楼层数 .  那么用d[i][j]表示用i个球,实验j次所能确定的最高楼层数 . 那么我们如果第j次实验是在k楼,有两种可能: 1.球破了.那么状态怎样转移? 用了一个球,用了一次实验机会.所以最优情况一定是从d[i-1][j-1]转移过来的,所以这一次实验向下所能确定的最大楼层数为d[i-1][j-1] + 1 :2.球没有破.那么

Dropping water balloons UVA - 10934(递推)

Dropping water balloons UVA - 10934 题意: 可以说是很懵比了... 和上一个题有相似之处,就是我们需要判断的结果是一个未知量.如本题气球的硬度,可能为1,2,3,------,n,n+1. 最坏情况需要测到n楼才知道结果.题目要求确定气球硬度,我们要考虑所有情况.[即我们要求的是最少测几次才可以测到n楼.] 用d[i][j]表示i个气球j次试验最多测到d[i][j]楼(即运气足够好的情况下可以测到几层楼)[这也是题目要求的,最少几次!!] (上面这两条红字放一

UVa 10934 DP Dropping water balloons

首先想一下特殊情况,如果只有一个气球,我们要确定高度只能从下往上一层一层地测试,因为如果气球一旦爆了,便无法测出气球的硬度. 如果气球有无数个,那么就可以用二分的方法来确定. 一般地,用d(i, j)表示用i个气球实验j次所能确定的楼层的最大高度. 我们假设第一个气球从第k层扔下, 如果气球爆了,那么剩下的i-1个气球实验j-1次,要能在下面的k-1层确定气球的硬度.所以这个k最大取d(i-1, j-1)+1 气球没爆,那么第1~k层就完全不用管了,i个气球剩下的j-1次测试就直接往上测试就行,

Dropping water balloons (入门dp)

2017-08-12 18:36:24 writer:pprp 最近刚刚接触动态规划,感觉状态的查找和转移自己很难想到,都是面向题解编程,但是一开始都是这样了,只有相信我可以独立自己解决动态规划这类问题: 题意:给你N个水球,M个楼 水球可能在某个楼层上释放就会破裂,问最少在几次内就可以得到水球破裂的临界楼层 如果次数大于63那就输出:More than 63 trials needed. 状态分析: dp[i][j] : 表示在目前有i个水球,还有j次释放机会时最多可以测到第几层 状态转移:

uva10934 Dropping water balloons

//好久没做题 一直没状态 然后刷了个水题玩玩 //寒假集训和校赛都做到了类似的题目 然而当时并不会 (其实现在也不会 题意:有k个气球和一个n层高的楼,气球有硬度,在某曾会恰好摔碎,问至少多少次实验可以求出来恰好摔碎的楼层. 解:分两种情况讨论:当前楼层破,当前楼层不破,然后f[i][j]表示i个气球实验j次能测到的最高楼层,于是乎f[i][j]=j[i-1][j-1]+f[i][j-1]+1 1 #include<cstdio> 2 #include<iostream> 3 #

[2016-02-08][UVA][679][Dropping Balls]

UVA - 679 Dropping Balls Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu Submit Status Description A number of K balls are dropped one by one from the root of a fully binary tree structure FBT. Each time the ball being dropped f

UVa 679 Dropping Balls (例题 6-6)

传送门:https://uva.onlinejudge.org/external/6/p679.pdf 题意:在一颗结点带开关的完全二叉树上扔球,初始时开关为关闭状态,树的深度为D(1 <= D <= 20), 根结点为1(节点从1开始到2D-1),开关为关闭向左子结点走,否则往右子结点走,每到一个结点改变该结点开关状态.问第 I 颗球落在哪. 当 I 是奇数时, 它是往当前结点的左子结点走的第 (I + 1) / 2 颗球; 当 I 是偶数时, 它是往当前结点的右子结点走的第 I / 2 颗

UVa 679 - Dropping Balls

称号:有一个完整的二叉树,每个节点是一个开关,最初的全封闭,球从顶点丢弃. 每次通过开关球将将其状态反转.现在先问k球落到d当层交换机经过号. 分析:进制编码.经过模拟几次能够看出,球会让开关形成连续二进制数的表示(根是低位). 当放入第k个球时.开关状态正好是二进制的k.利用模2的余数推断走向就可以. 说明:观察规律模拟处理就可以. #include <iostream> #include <cstdlib> #include <cstring> #include &