题意:有k种不同的水晶,每天等概率出现一个,q次询问至少多少天可以满足出现k种的概率大于pi / 2000
思路:
对于k种水晶,至少k天才能使所有水晶出现的概率不为0,对于当天出现的水晶,分为两种情况,第一种:这个水晶以前出现过了。 第二种:这个水晶以前没出现过。
则用dp[i][j]表示第i天出现了j种水晶的概率,则dp[i][j] = dp[i-1][j]*(j/k) + dp[i-1][j-1]*(j-k+1)/k;
式中第一项,表示第i-1天已经出现了j种水晶,那么这一天仍然出现j种水晶的概率就是再出现这j种中的一种,第二项则表示出现了新的一种。
则dp[i][k]则表示第i天出现了k种水晶的概率
由于需要的天数未定,但询问q小于1e3,k也小于1e3。所以可以先求出所有可能询问的结果,然后O(1)查询。
代码:
#include<iostream>
#include<algorithm>
using namespace std;
long long ans[1005];
double dp[10005][1005];
int k, q;
int main()
{
cin >> k >> q;
dp[0][0] = 1.0;
int p = 1;
for(int i = 1; p <= 1000; ++i)
{
for(int j = 1; j <= k; ++j)
dp[i][j] = (dp[i-1][j]*j + dp[i-1][j-1]*(k-j+1))/k;
while(p <= 1000 && dp[i][k]*2000 > p)
ans[p++] = i;
}
for(int i = 0; i < q; ++i)
{
int n;
cin >> n;
cout << ans[n] << endl;
}
}