题意:给出一个有n面的色子,求要看见所有面所需要投掷的期望次数。
解析:经典的题型,有两种解题思路:
①.利用几何分布:几何分布(Geometric distribution)是离散型概率分布。其中一种定义为:在n次伯努利试验中,试验k次才得到第一次成功的机率。详细地说,是:前k-1次皆失败,第k次成功的概率。几何分布概率为p时期望E(X) = 1/p;
又因为:
第一个面第一次出现的概率是n/n;
第二个面第一次出现的概率是(n-1)/n;
第三个面第一次出现的概率是(n-2)/n;
...
第 i 个面第一次出现的概率是(n-i+1)/n;
所以所求期望为∑1/pi = n * (1+1/2+1/3+1/4+1/5+...+1/n);
几何分布代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
double ans;
int t,n,i,cas;
scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
scanf("%d",&n);
ans=0;
for(i=1;i<=n;i++)
ans+=(1.0/i);
ans*=n;
printf("Case %d: %.7lf\n",cas,ans);
}
return 0;
}
②.dp思路:
设F(i)为看见i面的期望值。那么F(i) = (F(i - 1) + 1) * ((i - 1) / n) + (F(i) + 1) * ((n - (i - 1)) / n)。
即总共看见i面的期望值=这次看到的面是新的一面的期望+这次看面的是以前就看到过某个面的期望
即总共看见i面的期望值=(之前共看见i-1 面的期望值+这次新看的一次)*(这次看到第 i 面,即新的一面的概率)+ (之前共就看见过i面的期望值+这次新看的一次)*(这次看到的面是以前就看到过某个面的概率)
上面公式化简:F(i) = F(i - 1) + (n / (i - 1))或dp[i + 1] = n / (n - i) + dp[i] + 1
dp代码:
#include <bits/stdc++.h> using namespace std; const int M = 1e5+10; double dp[M]; int main() { int T; scanf("%d", &T); int cas = 0; while(T--) { int n; scanf("%d", &n); dp[1] = 1.0; for(int i = 2; i <= n; i++) { dp[i] = dp[i-1] + double(n) / (double(i) - 1.0); } printf("Case %d: %.7lf\n", ++cas, dp[n]); } }