我概率期望真是垃圾……,这题搞了两个钟头……

题意

有\(n\)个人,\(m\)个浴室,每个浴室里有\(a_i\)个浴缸。每个人会等概率随机选择一个浴室,然后每个浴室中尽量平分到每个浴缸。问期望最长排队队伍长度是多少?

解题思路

我看网上的题解都是直接\(DP\)期望,然而本蒟蒻看不懂那个递推式是什么鬼……有没有\(dalao\)来解释一下啊……

付一下别人的题解,摘自https://www.cnblogs.com/LzyRapx/p/7692702.html

用状态$ dp[i][j][k] \(表示还剩\) i$ 间浴室,还剩 \(j\) 个人,之前最长队伍的长度为 \(k\) 的期望最长队伍长度。

那么状态转移方程为:

\[dp[i][j][k]=∑^m_{i=1}∑^n_{j=0}∑^n_{k=1}∑^j_{c=1}(dp[i−1][j−c][max(k,(c+a[i]−1)/a[i])]\times
(i−1)^{j−c}/i^j \times (j,c))
\]

其中 \(c\) 是枚举当前去第 \(j\) 间浴室的人数。

那么答案就是$ dp[m][n][0]$ 。

----伪分割线----

下面是我自己的概率做法。

我们令\(dp[i][j][k]\)表示已经选了\(i\)个浴室,还剩\(j\)个人,最长长度为\(k\)的概率。注意下标意义的定义与上面的不一样。

那么我们可以得到状态转移方程:

\[dp[i+1][j-c][max(k, \frac{c+a[i+1]-1}{a[i+1]})] += dp[i][j][k]\times {j \choose c} / m^c
\]

这里感谢\(PSCdalao\)帮我斧正这个方程,并阐述了为什么是除以\(m^c\)。

下面我们解释这个方程的意义。

现在在状态\(dp[i][j][k]\),那么我们可以从剩下\(j\)个人中,选出\(c\)个。这时候下标就变为了\(dp[i+1][j-c][max(k, \frac{c+a[i+1]-1}{a[i+1]})]\)。而从前一个状态转到这一个方案的概率就是\({j \choose c} / m^c\)(从\(j\)个人中选\(c\)个,而这\(c\)个人本来可以有\(m^c\)种选法)。我们再来仔细看一下为什么是\(m^c\)而不是\((m-i)^c\)。

我们把n个人分到m个澡堂的某种分法的概率应当为

\[\frac{{n\choose p_1}{n-p_1\choose p_2}{n-p_1-p_2\choose p_3}...}{m^n}
\]

然后我们拆开分别乘在每一步中,就成了

\[\frac{{n\choose p_1}}{m^{p_1}} \times \frac{{n-p_1\choose p_2}}{m^{p_2}} \times \frac{{n-p_1-p_2\choose p_3}}{m^{p_3}}...
\]

所以就有方程中的“\(/m^c\)”。

同时,我们可以看出,我们同样可以先求出方案数,最后再除以\(m^c\)。(感谢\(DYTdalao\)提供这个好主意)

到这里,我们求出了概率。最后把每一个概率乘以长度,累加就好了。

不要问我精度问题,反正全部开\(double\),然后什么都不管就可以了QwQ

参考程序

#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int Maxn = 60;
int n, m, a[ Maxn ];
double dp[ Maxn ][ Maxn ][ Maxn ], C[ 60 ][ 60 ]; double Power( double x, int y ) {
if( y == 0 ) return 1.0;
double t = Power( x, y / 2 );
t = t * t;
if( y % 2 == 1 ) t = t * x;
return t;
} void init() {
memset( C, 0, sizeof( C ) );
C[ 0 ][ 0 ] = 1.0;
for( int i = 1; i <= 50; ++i ) {
C[ i ][ 0 ] = 1.0;
for( int j = 1; j <= i; ++j ) C[ i ][ j ] = C[ i - 1 ][ j - 1 ] + C[ i - 1 ][ j ];
}
return;
} int main() {
init();
memset( dp, 0, sizeof( dp ) );
scanf( "%d%d", &n, &m );
dp[ 0 ][ n ][ 0 ] = 1.0;
for( int i = 1; i <= m; ++i ) scanf( "%d", &a[ i ] );
for( int i = 0; i < m - 1; ++i )
for( int j = 0; j <= n; ++j )
for( int k = 0; k <= n; ++k )
for( int c = 0; c <= j; ++c )
dp[ i + 1 ][ j - c ][ max( k, ( c + a[ i + 1 ] - 1 ) / a[ i + 1 ] ) ] +=
dp[ i ][ j ][ k ] * C[ j ][ c ] / Power( m * 1.0, c );
for( int j = 0; j <= n; ++j )
for( int k = 0; k <= n; ++k )
dp[ m ][ 0 ][ max( k, ( j + a[ m ] - 1 ) / a[ m ] ) ] += dp[ m - 1 ][ j ][ k ] * 1.0 / Power( m * 1.0, j );
double ans;
for( int i = 0; i <= n; ++i )
ans += i * dp[ m ][ 0 ][ i ];
printf( "%.10lf\n", ans );
return 0;
}

CodeForces - 28C Bath Queue 概率与期望的更多相关文章

  1. Codeforces 28C Bath Queue 【计数类DP】*

    Codeforces 28C Bath Queue LINK 简要题意:有 n 个人等概率随机进入 m 个房间,一个房间可以有多个人,第 i 个房间有 ai 个水龙头,在一个房间的人要去排队装水,他们 ...

  2. Codeforces #28 C.Bath Queue (概率dp)

    Codeforces Beta Round #28 (Codeforces format) 题目链接: http://codeforces.com/contest/28/problem/C 题意: 有 ...

  3. Codeforces 1009E Intercity Travelling | 概率与期望

    题目链接 题目大意: 一个人要从$A$地前往$B$地,两地相距$N$千米,$A$地在第$0$千米处,$B$地在第$N$千米处. 从$A$地开始,每隔$1$千米都有$\dfrac{1}{2}$的概率拥有 ...

  4. 【CodeForces】913 F. Strongly Connected Tournament 概率和期望DP

    [题目]F. Strongly Connected Tournament [题意]给定n个点(游戏者),每轮游戏进行下列操作: 1.每对游戏者i和j(i<j)进行一场游戏,有p的概率i赢j(反之 ...

  5. 概率及期望DP小结

    资源分享 26 个比较概率大小的问题 数论小白都能看懂的数学期望讲解 概念 \(PS\):不需要知道太多概念,能拿来用就行了. 定义 样本(\(\omega\)):一次随机试验产生的一个结果. 样本空 ...

  6. 【算法学习笔记】概率与期望DP

    本文学习自 Sengxian 学长的博客 之前也在CF上写了一些概率DP的题并做过总结 建议阅读完本文再去接着阅读这篇文章:Here 前言 单纯只用到概率的题并不是很多,从现有的 OI/ACM 比赛中 ...

  7. 【BZOJ-3450】Tyvj1952Easy 概率与期望DP

    3450: Tyvj1952 Easy Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 468  Solved: 353[Submit][Status] ...

  8. 【BZOJ-4008】亚瑟王 概率与期望 + DP

    4008: [HNOI2015]亚瑟王 Time Limit: 20 Sec  Memory Limit: 512 MBSec  Special JudgeSubmit: 832  Solved: 5 ...

  9. BZOJ_4872_[Shoi2017]分手是祝愿_概率与期望

    BZOJ_4872_[Shoi2017]分手是祝愿_概率与期望 Description Zeit und Raum trennen dich und mich. 时空将你我分开.B 君在玩一个游戏,这 ...

随机推荐

  1. ubuntu 18.04 配置notebook远程连接的坑

    jupyter-notebook的安装不在此说明 在网上搜了很多方案都不行,好不容易从坑里爬出来 以下为远程连接配置方法 1.生成配置文件 jupyter notebook --generate-co ...

  2. 使用TableSnapshotInputFormat读取Hbase快照数据

    根据快照名称读取hbase快照中的数据,在网上查了好多资料,很少有资料能够给出清晰的方案,根据自己的摸索终于实现,现将代码贴出,希望能给大家有所帮助: public void read(org.apa ...

  3. C# 面向对象6 之前的复习

    复习练习 THIS:调用当前类的构造函数

  4. MySQL存储引擎知多少

    MySQL是我们经常使用的数据库处理系统(DBMS),不知小伙伴们有没有注意过其中的“存储引擎”(storage_engine)呢?有时候面试题中也会问道MySQL几种常用的存储引擎的区别.这次就简短 ...

  5. 两个实体类 复制 copy 工具类

    import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Date; public class ...

  6. 精通shell编程--最后的总结

    不得不说shell语法是丑陋的,操作是简单高效的,最后一次学习总结shell shell总结 字符串删除与替换等常见操作 ## 字符串长度 a=1234 echo "${#a}" ...

  7. JS常用自定义函数总结

    JS常用自定义函数总结   1.原生JavaScript实现字符串长度截取 2.原生JavaScript获取域名主机 3.原生JavaScript清除空格 4.原生JavaScript替换全部 5.原 ...

  8. python 安装时,为何pip install不是内部或者外部命令错误解决办法

    新安装的python 环境,第一次pip  install 却报不是内部或者外部命令错误 首先检查一下环境变量,可能时你没有设置环境变量 再说一遍,安装python环境时,记得出了python.exe ...

  9. 关于gitlab+jenkins自动部署代码的实现

    本人PHP开发者,项目组大多是PHP,少量java项目. 因公司目前服务器和项目的管理比较混乱,与领导商量后,决定尝试 gitlab+jenkins自动化部署(之前用的svn FTP手动部署代码),解 ...

  10. 通用mapper将另外一个同名的表生成在同一个实体及mapper中

    今天遇见了一个在网上都搜索不到的错误,使用通过mapper生成实体及mapper文件时会将另外一个数据库的同名文件生成在一个实体及mapper中,这样就会造成一个实体和mapper中有两个表的字段,经 ...