题目链接:LightOJ - 1248

Description

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.5^2 + 0.5^3 + ...\)

\(= 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 ≤ 10^5)\).

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

5
1
2
3
6
100

Sample Output

Case 1: 1
Case 2: 3
Case 3: 5.5
Case 4: 14.7
Case 5: 518.7377517640

Solution

题意

给定一个 \(n\) 面的骰子,每个面出现的概率相同,现在要所有的面都至少出现一次,求投掷次数的期望。

思路

期望DP

期望DP一般是倒推的。

设 \(dp[i]\) 为已经出现了 \(i\) 个面,还需要投掷次数的期望值。

那么每次投掷只有两种情况:出现已经出现过的面、出现未出现的面。前者概率为 \(\frac{i}{n}\),后者概率为 \(\frac{n - i}{n}\)。

则状态转移方程为 \(dp[i] = (dp[i] + 1) * \frac{i}{n} + (dp[i + 1] + 1) * \frac{n - i}{n}\)

化简得 \(dp[i] = dp[i + 1] + \frac{n}{n - i}\)

\(dp[n] = 0\),倒推即可。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10; double dp[maxn]; int main() {
int T;
scanf("%d", &T);
int kase = 0;
while(T--) {
memset(dp, 0, sizeof(dp));
int n;
scanf("%d", &n);
dp[n] = 0;
for(int i = n - 1; i >= 0; --i) {
dp[i] = dp[i + 1] + 1.0 * n / (n - i);
}
printf("Case %d: %.10lf\n", ++kase, dp[0]);
}
return 0;
}

其实是满足几何分布的。

第一个出现的面可以是 \(1, 2, 3, ..., n\),有 \(n\) 个。

如果第一个出现的面是 \(1\),那么第二个出现的面可以是 \(2, 3, ..., n\),有 \(n - 1\) 个。

...

第一个面第一次出现的概率为 \(p_1 = \frac{n}{n}\)

第二个面第一次出现的概率为 \(p_2 = \frac{n - 1}{n}\)

第三个面第一次出现的概率为 \(p_3 = \frac{n - 2}{n}\)

...

第 \(i\) 个面第一次出现的概率为 \(p_i = \frac{n - i + 1}{n}\)

几何分布的期望 \(E(X) = \frac{1}{p}\)

所以所有面至少出现一次的期望为 \(\sum_{i=1}^n \frac{1}{p_i} = \sum_{i=1}^n \frac{n}{n - i + 1}\)。

注:几何分布指在 \(n\) 次伯努利试验中,试验 \(k\) 次才得到第一次成功的机率。

#include <bits/stdc++.h>
using namespace std; int main() {
int T;
scanf("%d", &T);
int kase = 0;
while(T--) {
int n;
scanf("%d", &n);
double ans = 0.0;
for(int i = 1; i <= n; ++i) {
ans += n * 1.0 / i;
}
printf("Case %d: %.10lf\n", ++kase, ans);
}
return 0;
}

Reference

LightOJ - 1248 Dice (III) (概率期望+几何分布)

LightOJ 1248 Dice (III) (期望DP / 几何分布)的更多相关文章

  1. LightOJ - 1248 Dice (III) —— 期望

    题目链接:https://vjudge.net/problem/LightOJ-1248 1248 - Dice (III)    PDF (English) Statistics Forum Tim ...

  2. LightOj 1248 - Dice (III)(几何分布+期望)

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1248 题意:有一个 n 面的骰子,问至少看到所有的面一次的所需 掷骰子 的 次数的期望 ...

  3. LightOJ 1248 Dice (III) (水题,期望DP)

    题意:给出一个n面的色子,问看到每个面的投掷次数期望是多少. 析:这个题很水啊,就是他解释样例解释的太...我鄙视他,,,,, dp[i] 表示 已经看到 i 面的期望是多少,然后两种选择一种是看到新 ...

  4. 【非原创】LightOj 1248 - Dice (III)【几何分布+期望】

    学习博客:戳这里 题意:有一个 n 面的骰子,问至少看到所有的面一次的所需 掷骰子 的 次数的期望: 第一个面第一次出现的概率是p1 n/n; 第二个面第一次出现的概率是p2 (n-1)/n; 第三个 ...

  5. LightOJ 1248 Dice (III) 概率

    Description Given a dice with n sides, you have to find the expected number of times you have to thr ...

  6. LightOJ 1248 Dice (III)

    期望,$dp$. 设$dp[i]$表示当前已经出现过$i$个数字的期望次数.在这种状态下,如果再投一次,会出现两种可能,即出现了$i+1$个数字以及还是$i$个数字. 因此 $dp[i]=dp[i]* ...

  7. 1248 - Dice (III)

    1248 - Dice (III)   PDF (English) Statistics Forum Time Limit: 1 second(s) Memory Limit: 32 MB Given ...

  8. [LOJ 1248] Dice (III)

    G - Dice (III) Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Descri ...

  9. lightoj 1248-G - Dice (III) (概率dp)

    题意:给你n个面的骰子,问扔出所有面的期望次数. 虽然这题挺简单的但还是要提一下.这题题目给出了解法. E(m)表示得到m个不同面的期望次数. E(m+1)=[((n-m)/n)*E(m)+1]+(m ...

随机推荐

  1. 记C函数指针的“小坑”

    今天遇到一个C函数指针的小坑,索性记下来. 我在a.c 文件里面,引用b.c 文件的函数声明作为指针引用 比如在a.c生命一个函数指针 typedef void (*free)(void *val) ...

  2. 详解linux io flush

    通过本文你会清楚知道 fsync().fdatasync().sync().O_DIRECT.O_SYNC.REQ_PREFLUSH.REQ_FUA的区别和作用. fsync() fdatasync( ...

  3. PHP递归获得树形菜单和遍历文件夹下的所有文件以及子文件夹

    PHP递归获得树形菜单和遍历文件夹下的所有文件以及子文件夹 一.使用递归获取树形菜单 数据表category(id,name,parent_id) <?php class category{ / ...

  4. Java必备主流技术流程图,写得非常好!

    作者:Jay_huaxiao https://juejin.im/post/5d214639e51d4550bf1ae8df 1.spring的生命周期 Spring作为当前Java最流行.最强大的轻 ...

  5. Django上线部署之uWSGI

    环境: 1.CentOS 7.2 64位 2.SQL Server 2016 Enterprise 64位 3.Python 3.6.5 64位 4.root用户 要求: 按照顺序部署 1.Windo ...

  6. 一些常ArcGIS常用简单算法 C#

    最近开始重构不顺眼的辣鸡代码,顺带将某个模块的一个算法辅助类贴到这里. /// <summary> /// 算法逻辑辅助类 /// </summary> internal st ...

  7. C# 中类重写 ToString 方法

    一,C# 中的每个类或结构都隐式继承 Object 类.因此,C# 中的每个对象都会获得 ToString 方法,此方法返回该对象的字符串表示形式.而同时在Object 中的ToString是虚方法则 ...

  8. sub

    Popen.communicate(input=None)¶Interact with process: Send data to stdin. Read data from stdout and s ...

  9. Linux帮助用法

    内部命令: help COMMAND 或 man bash 外部命令: (1) COMMAND --helpCOMMAND -h(2) 使用手册(manual)man COMMAND(3) 信息页in ...

  10. dictionary小项目代码管理

    软件项目开发流程 需求分析 ----> 概要设计  ---> 项目计划 ---->详细设计--->编码测试 -----> 项目测试 ---->调试修改 ---> ...