uva 10934(dp)

题意:k个水球,现在在一个n层建筑物上,水球可能在某一层层以上扔下去会破掉,现在求一个最少的次数使得用这k个水球能确定出哪一层。

思路:假设有i个小球,还可以实验j次时,第一个小球从x处扔下去,如果破了,那么可以确定答案肯定在x之下找,剩下i-1个小球和j-1次实验,可以在x之下确定出最高层数,那么x-1就是这最高层数(试想如果x-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 - 1][j];

#include <cstdio>
#include <iostream>
#include <sstream>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <algorithm>
using namespace std;
#define ll long long
#define _cle(m, a) memset(m, a, sizeof(m))
#define repu(i, a, b) for(int i = a; i < b; i++)
#define repd(i, a, b) for(int i = b; i >= a; i--)
#define sfi(n) scanf("%d", &n)
#define pfi(n) printf("%d
", n)
#define sfi2(n, m) scanf("%d%d", &n, &m)
#define pfi2(n, m) printf("%d %d
", n, m)
#define pfi3(a, b, c) printf("%d %d %d
", a, b, c)
#define MAXN 105
const int INF = 0x3f3f3f3f;
#define ull unsigned long long
ull dp[MAXN][65];
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#include <cstring>
using namespace std;

typedef long long int64;

int64 f[110][65];

inline void init() {
    memset(f, 0, sizeof(f));
    for (int i = 1; i < 64; ++i) {
        for (int j = 1; j < 64; ++j) {
            f[i][j] = f[i][j-1] + f[i-1][j-1] + 1;
        }
    }
}
int main(){

    init();
    int k;
    int64 n;

    while (~scanf("%d%lld", &k, &n) && k) {
        k = min(63, k);
        bool ok = false;
        for (int i = 0; i <= 63; ++i) {
            if (f[k][i] >= n) {
                printf("%d
", i);
                ok = true;
                break;
            }
        }
        if (!ok) puts("More than 63 trials needed.");
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/sunus/p/4845454.html