Problem

有无数包牌,每包有 \(N\) 张牌。在每一包牌中, 第 \(i\) 张牌是稀有牌,概率为 \(P_i\%\)。每张牌是否稀有与其他牌是否稀有无关。

逐一打开包装,并获得每包中的所有卡片。当你一直开包直到总共获得至少 \(X\) 张稀有卡牌时,求你开包的预期次数。

Constraints

\(1 \leq N \leq 5000,1 \leq X \leq 5000,1 \leq P_i \leq 100\)

Solution

该问题可以分为两个部分。

首先,求出开一包卡牌将会得到的稀有卡牌数量的分布列

这是一个多元二项分布问题,直接暴力计算的话需要枚举一包卡牌的子集。

考虑动态规划。设 \(dp_{i,j}\) 为一包卡牌内前 \(i\) 张牌中存在 \(j\) 张稀有牌的概率。\(dp_{i,j}\) 可由两个状态转移:原本抽到了 \(j-1\) 张稀有牌,再翻一张发现正好是稀有牌;原本抽到了 \(j\) 张稀有牌,再翻一张发现不是稀有牌。故转移方程为:

\[\begin{align}
dp_{i,j}=dp_{i-1,j-1}\times \frac{P_i}{100}+dp_{i-1,j}\times\frac{(1-P_i)}{100}
\end{align}
\]

其中,\(dp_{0,0}=1,dp_{i,j}=0(j<0)\)。

通过上述动态规划得到 \(P(开一包卡牌得到j张稀有卡牌)=dp_{n,j}\),将其记作 \(Y_j\)。

接着解决第二个问题:已知开一包卡牌得到的稀有卡牌数量分布列为 \(Y_j\),求开出 \(X\) 张稀有牌的期望开包次数

设得到 \(i\) 张稀有牌的期望开包次数是 \(E_i\)。对于 \(i=0\),有 \(E_i=0\)。模拟一次开包,将会有 \(Y_j\) 的概率获得 \(j\) 张稀有牌。所以有:

\[\begin{align}
E_i=1+\sum_{j=0}^nE_{\max(i-j,0)}\cdot Y_j
\end{align}
\]

但是这个方程左右两侧都有 \(E_i\) 项(\(j=0\) 时),所以不能简单的递推。

将式子变换一下:

\[\begin{align}
E_i&=1+E_i\cdot Y_0+\sum_{j=1}^nE_{\max(i-j,0)}\cdot Y_j\\
E_i\times(1-Y_0)&=1+\sum_{j=1}^nE_{\max(i-j,0)}\cdot Y_j\\
E_i&=\frac{1+\sum_{j=1}^nE_{\max(i-j,0)}\cdot Y_j}{(1-Y_0)}
\end{align}
\]

Code

#define N 6010

int n,m;
double p[N];
double dp[N][N];
double E[N];
void solve()
{
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>p[i],p[i]/=100;
dp[0][0]=1; //起始条件,抽前0张牌的时候得到0张稀有牌的概率是100%
for(int i=1;i<=n;i++)
{
for(int j=0;j<=i;j++)
{
//抽前i张卡牌,正好得到j张稀有牌的概率是dp[i][j]
if(j==0) dp[i][j]=dp[i-1][j]*(1-p[i]); //防止越界
else dp[i][j]=dp[i-1][j-1]*p[i]+dp[i-1][j]*(1-p[i]);
}
}
//此时得到了开一次包的概率分布表(得到j张稀有牌)为dp[n][j]
for(int j=0;j<=n;j++)
{
// DEBUG(j,1);
// DEBUG(dp[n][j],2);
}
for(int i=1;i<=m;i++)
{
//得到i张稀有牌的期望开包次数是E[i]
for(int j=1;j<=n;j++)
{
if(i-j>=0) E[i]+=(E[i-j])*dp[n][j];
else E[i]+=(0)*dp[n][j];
}
E[i]=(1+E[i])/(1-dp[n][0]);
}
cout<<E[m]<<endl;
}

AtCoder Beginner Contest 382-E的更多相关文章

  1. AtCoder Beginner Contest 100 2018/06/16

    A - Happy Birthday! Time limit : 2sec / Memory limit : 1000MB Score: 100 points Problem Statement E8 ...

  2. AtCoder Beginner Contest 052

    没看到Beginner,然后就做啊做,发现A,B太简单了...然后想想做完算了..没想到C卡了一下,然后还是做出来了.D的话瞎想了一下,然后感觉也没问题.假装all kill.2333 AtCoder ...

  3. AtCoder Beginner Contest 053 ABCD题

    A - ABC/ARC Time limit : 2sec / Memory limit : 256MB Score : 100 points Problem Statement Smeke has ...

  4. AtCoder Beginner Contest 136

    AtCoder Beginner Contest 136 题目链接 A - +-x 直接取\(max\)即可. Code #include <bits/stdc++.h> using na ...

  5. AtCoder Beginner Contest 137 F

    AtCoder Beginner Contest 137 F 数论鬼题(虽然不算特别数论) 希望你在浏览这篇题解前已经知道了费马小定理 利用用费马小定理构造函数\(g(x)=(x-i)^{P-1}\) ...

  6. AtCoder Beginner Contest 076

    A - Rating Goal Time limit : 2sec / Memory limit : 256MB Score : 100 points Problem Statement Takaha ...

  7. AtCoder Beginner Contest 079 D - Wall【Warshall Floyd algorithm】

    AtCoder Beginner Contest 079 D - Wall Warshall Floyd 最短路....先枚举 k #include<iostream> #include& ...

  8. AtCoder Beginner Contest 064 D - Insertion

    AtCoder Beginner Contest 064 D - Insertion Problem Statement You are given a string S of length N co ...

  9. AtCoder Beginner Contest 075 D - Axis-Parallel Rectangle【暴力】

    AtCoder Beginner Contest 075 D - Axis-Parallel Rectangle 我要崩溃,当时还以为是需要什么离散化的,原来是暴力,特么五层循环....我自己写怎么都 ...

  10. AtCoder Beginner Contest 075 C bridge【图论求桥】

    AtCoder Beginner Contest 075 C bridge 桥就是指图中这样的边,删除它以后整个图不连通.本题就是求桥个数的裸题. dfn[u]指在dfs中搜索到u节点的次序值,low ...

随机推荐

  1. PyCharm一直indexing,且永不停止。

  2. 基础指令:mkdir、ls、cd、pwd、touch、rm、mv、cp、echo、cat、关机与重启

    目录 1. 创建目录 2. 查看目录内容 3. 进入指定目录(传送) 4. 显示当前所在位置 5. 创建文件 6. 删除文件或目录 7. 移动文件 8. 复制文件或目录 9. echo输出信息到屏幕 ...

  3. Ubuntu 下查看当前用户

    博客地址:https://www.cnblogs.com/zylyehuo/ 在终端执行以下命令 whoami

  4. Delphi Richedit代码语法加亮显示

    procedure CodeColors(Form : TForm;Style : String; RichE : TRichedit;InVisible : Boolean); const // s ...

  5. Python提取pdf文字信息

    目录 Python提取pdf文字信息 需求 代码 总结 Python提取pdf文字信息 需求 今天教务处导出来我们全年级的成绩,一看吓一跳,我们的名字怎么不在文件名里,只能一个个找吗.事情开始变得离谱 ...

  6. DeepSeek 官方推出的实用集成工具百宝箱,建议收藏!

    项目介绍 该实用集成工具百宝箱汇聚了DeepSeek官方精心挑选和推荐的各类集成工具(其中包括:应用程序.AI Agent 框架.AI数据应用框架.RAG 框架.浏览器插件.VS Code 插件等), ...

  7. 适配器设计模式--java进阶day03

    1.设计模式 通俗来讲,设计模式就是其他程序员遇到某些问题时的解决经验,我们学习设计模式,在遇到了同样的问题后便可解决 2.适配器设计模式 有人可能会感到疑惑,接口和实现类会有什么问题,我们举两个例子 ...

  8. 【Unity】改变游戏运行时Window的窗口标题

    [Unity]改变游戏运行时Window的窗口标题 零.需求 Unity打包好的Windows程序,启动后如何更改窗口标题?因为看着英文的感觉不太好,故有此想法.什么?你说为啥不改项目产品名?产品名会 ...

  9. DRG,医改分水岭!

    2020-11-04 (2021年政府推出2.0版DRG.增加MCC和CC,各自政府的医保支付中增加了人性化的支付倍率的处理) 假设某疾病病组支付标准10000元,患者自付自费比例40%,分三种情况, ...

  10. Eclipse 配置maven默认源及本地仓库

    1.window->Preferences 2.Maven-> User Setting 3.全局配置Global Settings/用户配置 User  Settings 修改为自己的配 ...