1248 - Dice (III)
PDF (English) Statistics Forum
Time Limit: 1 second(s) Memory Limit: 32 MB
Given a dice with n sides, you have to find the expected number of times you have to throw that dice to see all its faces at least once. Assume that the dice is fair, that means when you throw the dice, the probability of occurring any face is equal.
For example, for a fair two sided coin, the result is 3. Because when you first throw the coin, you will definitely see a new face. If you throw the coin again, the chance of getting the opposite side is 0.5, and the chance of getting the same side is 0.5. So, the result is
1 + (1 + 0.5 * (1 + 0.5 * ...))
= 2 + 0.5 + 0.52 + 0.53 + ...
= 2 + 1 = 3
Input
Input starts with an integer T (≤ 100), denoting the number of test cases.
Each case starts with a line containing an integer n (1 ≤ n ≤ 105).
Output
For each case, print the case number and the expected number of times you have to throw the dice to see all its faces at least once. Errors less than 10-6 will be ignored.
Sample Input
Output for Sample Input
5
1
2
3
6
100
Case 1: 1
Case 2: 3
Case 3: 5.5
Case 4: 14.7
Case 5: 518.7377517640
题意:
一个均匀的骰子有n个面 投色子, 要求最后要把骰子的每一面都看到了, 求扔骰子次数的期望。
分析:
1.几何分布
上面我们定义只要E(x)=1/P,P表示第k次成功的概率
扔出第一面成功的概率为P=1,E=1,因为第一面肯定没见过。
扔出第二面成功的概率为P=(n-1)/n,E=n/(n-1)(因为实验独立,所以有n-1个可以当作第二面)
扔出第i面成功的概率为P=(n-i-1)/n ,E=n/(n-i+1)
扔出第n面成功的概率为P=1/n ,E=n
累加E即可
2.期望DP
设dp[i]为已经扔了i个不同面的期望值 ,dp[n] = 0 求dp[0]
那我们每次可能扔中已经扔过的面或者没有扔到过的面2中情况:
1.该面在前面已经出现过概率:(i-1)/n,E= F(i - 1) * ((i - 1) / n)
2.该面已经未出现过概率:(n-(i+1))/n,E= F(i) * ((n - (i - 1)) / n)则状态方程:F(i) = F(i - 1) * ((i - 1) / n) + 1 + F(i) * ((n - (i - 1)) / n)。
解得F(i) = F(i - 1) + (n / (i - 1))。
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#define nmax 510
using namespace std;
int cas=0,T,n;
int main(){
scanf("%d",&T);
while(T--)
{
cas++;
cin>>n;
double sum=0;
//System.out.println(t);
for(int i=1;i<=n;i++){
sum+=n*1.0/i*1.0;
}
printf("Case %d: %lf\n",cas,sum);
}
}
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
double dp[maxn];
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: %.10lf\n", ++cas, dp[n]);
}
}