UVA 10934 Dropping water balloons(DP)

来源:互联网 发布:js树状图 饼图插件 编辑:程序博客网 时间:2024/04/29 00:20

链接:10934 - Dropping water balloons

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

这题想了好久,,终于想通了

思路:dp,一共就3个数据,k个小球,n层,求次数,其中n是非常大的,那么肯定不会选择用n去做状态了,于是想到利用小球数和次数去做状态,dp[i][j]表示i个小球,用了j次最多可以确定的层数。

状态的表示方法没问题了,然后就是状态转移的问题了。

题目要求的是最糟的情况下,那么我们知道,一个小球如果扔下去破了,那么层数肯定在后面找,如果扔下去没破,那么肯定在上面找。

那么假设有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],那么往下和往上能确定的层数加起来就是总的能确定的层数

dp[i][j] = dp[i - 1][j - 1] + 1 + dp[i - 1][j];

代码:

#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;int k, i, j;long long n, dp[105][65];int main() {for (i = 1; i < 64; i++)for (j = 1; j < 64; j++)dp[i][j] = dp[i][j - 1] + dp[i - 1][j - 1] + 1;while (~scanf("%d%lld", &k, &n) && k) {if (k >= 64) k = 63;int v = lower_bound(dp[k], dp[k] + 65, n) - dp[k];if (v < 64) printf("%d\n", v);else printf("More than 63 trials needed.\n");}return 0;}


2 0
原创粉丝点击