codeforces 768D Jon and Orbs
来源:互联网 发布:怎么自学javascript 编辑:程序博客网 时间:2024/05/22 06:25
题目链接:http://codeforces.com/problemset/problem/768/D
题意:给你概率 p/2000 ,k种东西,每种东西取到的概率相同。q次询问问取多少次能使得每种东西至少一个的概率能达到给定值。k,q,p小于1000。
题解:概率用dp递推,dp[i]代表已有 i 种东西的概率,滚动此数组来模拟取的次数,记录dp[k]为每次的答案方便询问查询。
由于p范围概率最大为0.5,在k取最大值1000时也只用大约7000多次循环即可达到这个概率。
dp方程:dp[i] = dp[i] * i / k + dp[i - 1] * (k - i + 1) / k
代码:
#include <iostream>#include <algorithm>#include <cmath>#include <cstring>#include <cstdio>#include <cstdlib>#include <vector>#include <stack>#include <set>#include <queue>#include <functional>#include <map>#include <bitset>#define INF 0x7fffffff#define REP(i,j,k) for(int i = j;i <= k;i++)#define squr(x) (x) * (x)#define lowbit(x) (x&(-x))#define getint(x) scanf("%d", &(x))using namespace std;typedef long long LL;typedef pair<int, int> pii;const int MAXN = 1e3 + 10;const double eps = 1e-7;int k, q;int p;double dp[MAXN];double ans[100010];int main(int argc, const char * argv[]) { getint(k); getint(q); dp[1] = 1; if (k == 1) { ans[1] = 1; } REP(i, 1, 10000) { for (int j = k; j > 0; j--) { dp[j] = dp[j] * (double)j / k + dp[j - 1] * (double)(k - j + 1) / k; } ans[i + 1] = dp[k]; //cout << pp[k] << endl; if (dp[k] > 0.6) { break; } } REP(i, 1, q) { getint(p); double tt = p / 2000.0; for (int i = 1; i <= 10000; i++) { if (ans[i] - tt >= 0) { printf("%d\n", i); break; } } } return 0;}
阅读全文