题目链接:http://codeforces.com/problemset/problem/768/D
令$f[i][j]$表示当前产生过了$i$个球,产生过了$j$个不同的球的概率。
${Ans_i=Minleft { x|f[x][k]>frac{p_i-varepsilon }{2000} ight }}$
考虑转移:
${f[i][j]=frac{j}{k}*f[i-1][j]+frac{k-j+1}{k}*f[i-1][j-1]}$
${f[0][0]=1}$
可能答案并不一定小于$K$所以我把$i$的上界设为了${k*10}$
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<vector> 5 #include<cstdlib> 6 #include<cmath> 7 #include<cstring> 8 using namespace std; 9 #define maxn 2100 10 #define llg int 11 #define UP 10000000 12 #define eps (double)(1e-7) 13 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); 14 llg n,T,m,l,r,mid,ans; 15 double f[maxn*5][maxn],p; 16 int main() 17 { 18 // yyj("D"); 19 cin>>n>>T; 20 //double N=n; 21 f[0][0]=1; 22 for (llg i=1;i<=n*10;i++) 23 for (llg j=1;j<=n;j++) 24 f[i][j]=((double)((double)j/n))*f[i-1][j]+(double)((double)(n-j+1)/n)*f[i-1][j-1]; 25 while (T--) 26 { 27 scanf("%lf",&p); 28 p=p-eps; p/=2000; //llg ans; 29 l=1; r=n*10; 30 while (l<=r) 31 { 32 mid=(l+r)>>1; 33 if (f[mid][n]>=p){ans=mid; r=mid-1;}else l=mid+1; 34 } 35 printf("%d ",ans); 36 } 37 return 0; 38 }