现在的位置: 首页 > 综合 > 正文

UVa #10934 Dropping water balloons (例题9-20)

2018年10月14日 ⁄ 综合 ⁄ 共 922字 ⁄ 字号 评论关闭

最初的想法应该是:d(i,j) 表示用 i 个球在高度为 j 的楼里做实验,需要的最少实验次数。

可是层数太大,无法作为状态。进行一下问题的转换:设 d(i,j) 表示用 i 个球做 j 次实验最高可以测试多少层楼。最后只需选取 d(k,j) >= n 的最小的 j 即可

状态的转移很有意思:

假设我们现在对 d(i,j) 做决策,如果气球爆了,则实验可以测定的层数等于 d(i-1, j-1) + 1。如果气球没爆,我们可以继续向上面的楼层搜索。向上最多能测定 d(i, j-1) 层。保证上下所有的楼层都能搜到,d(i,j) 最大值则是向下和向上搜索的层数的最大值的和,d(i-1, j-1) + 1 + d(i, j-1)。最后应该取爆/不爆两种情况的最大值,但是这里最大值一定来自不爆,所以可以直接转移到 d(i,j) = d(i-1, j-1) + 1 + d(i, j-1)。

Run Time: 0.015s

#define UVa  "LT9-20.10934.cpp"		//Dropping water balloons
char fileIn[30] = UVa, fileOut[30] = UVa;

#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;

//Global Variables. Reset upon Each Case!
const int maxk = 100 + 5, INF = 10000;
typedef long long LL;
int k;
LL  n;
LL dp[maxk][70];
/////

int main() {
    dp[0][0] = dp[0][1] = dp[1][0] = 0;
    for(int i = 1; i < maxk; i ++)
        for(int j = 1; j < 64; j ++)
            dp[i][j] = dp[i-1][j-1] + 1 + dp[i][j-1];

    while(scanf("%d%lld", &k, &n) && k) {
        int ans = -1;
        for(int i = 1; i <= 63; i ++) {
            if(dp[k][i] >= n) {
                ans = i;
                break;
            }
        }
        if(ans == -1) printf("More than 63 trials needed.\n");
        else printf("%d\n", ans);
    }
    return 0;
}

抱歉!评论已关闭.