UVa10934 - Dropping water balloons(经典dp)

112 篇文章 0 订阅

题目链接

简介:
气球的硬度
借助一个n层的楼确定气球的硬度,如果气球从第f层掉下,没有摔破,说明气球的硬度至少为f;否则说明气球的硬度不超过f
给你k个气球来做实验,求出至少需要多少次才能确定气球的硬度(或者得出结论:站在最高层也摔不破)

分析:
首先让我们读懂题,看一下输入输出:

Input
输入的每一行包含多组测试,每组测试为一行。每组测试包含两个整数 k 和 n, 1 <= k <= 100 而 n 是一个 64 位的整数(没错,这栋建筑物的确很高),最后一组k=0,n=0 代表结束,这组测试不用处理。
Output
对于每次测试,输出在最糟情况下,测出水球破掉楼层的最少次数。
如果他多于63次,就输出“More than 63 trials needed.”

注意到输出的限制中有一点很重要:在最糟情况下
什么是最糟情况呢?就是气球在最高层也摔不破
那么问题就转化成了:我们用k个气球,需要多少次才能测试到这栋楼最顶层

我们先不管气球个数的限制:假设我们有无数个气球
那么最优方案一定是二分,这样需要logn次

那如果我们只有一个气球呢?
这就比较悲惨了,我们只能从第一层开始试(毕竟我们只有这一个气球,要是摔破了就GG了)
最坏情况下我们需要实验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)

一定要牢牢的记住了~~~

//这里写代码片
#include<cstdio>
#include<cstring>
#include<iostream>
#define ll unsigned long long

using namespace std;

ll f[105][70];
int n;
ll k;

int main()
{
    while (scanf("%d%llu",&n,&k)!=EOF&&n)
    {
        f[0][0]=0;
        int ans=-1;
        for (int j=1;j<=63;j++)
            for (int i=1;i<=n&&ans==-1;i++)
            {
                f[i][j]=f[i-1][j-1]+1+f[i][j-1];
                if (f[i][j]>=k)
                {
                    ans=j;
                    break;
                }
            }
        if (ans==-1) printf("More than 63 trials needed.\n");
        else printf("%d\n",ans);
    }
    return 0;
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值