题意
有(n)个奖品,装在(n)个盒子内,每个盒子有且仅有一个奖品。
(m)个人,每人依次选奖品,选择方式是从(n)个盒子内随机选择一个盒子。
如果盒子内有奖品,则取走,否则没有获得任何奖品。
盒子始终是(n)个,空盒子也一直存在。
求送出奖品数量的期望。
分析
(dp[i][j])表示前(i)个人选了(j)个奖品的概率。
(Ans = sum_{j=0}^{n} dp[m][j] * j)
考虑转移
(dp[i][j] = dp[i - 1][j] * frac jn + dp[i - 1][j - 1] *frac{n - j + 1}{n})(分别是第(i)个人是否取到礼物的概率)
(dp[0][0]=1)
时间复杂度(O(n^2))
考虑优化
考虑物
(f_i)表示前(i)个人选择结束后剩下的奖品个数。
(f_i = f_{i-1} - frac {f_{i-1}}{n}) 前半部分是没拿到奖品,后半部分是拿到奖品。
(f_i = (1 - frac1n)f_{i-1} = (1 - frac 1n)^i f_0 = n(1 - frac 1n) ^i)(因为(f_0 = n)),可以实数快速幂优化。
(Ans = n - f_m)
code
#include<bits/stdc++.h>
using namespace std;
#define ld long double
ld ksm(ld x, int y){
ld ret = 1; for(; y; y >>= 1, x = x * x) if(y & 1) ret = ret * x;
return ret;
}
int n,m;
int main(){
scanf("%d%d",&n,&m);
printf("%.15Lf
",(ld)n - (ld)n * ksm(1.0 - 1.0 / n, m));
return 0;
}