洛谷 P5249 [LnOI2019]加特林轮盘赌 题解【概率期望】【DP】
很有意思的题目。
题目背景
加特林轮盘赌是一个养生游戏.
题目描述
与俄罗斯轮盘赌等手枪的赌博不同的是,加特林轮盘赌的赌具是加特林。
加特林轮盘赌的规则很简单:在加特林的部分弹夹中填充子弹。游戏的参加者坐在一个圆桌上,轮流把加特林对着自己的头,扣动扳机一秒钟。中枪的自动退出,坚持到最后的就是胜利者。
我们使用的是2019年最新技术的加特林,他的特点是无需预热、子弹无限,每一个人,在每一回合,中枪的概率是完全相同的 \(P_0\)。
每局游戏共有 \(n\) 只长脖子鹿,从1长脖子鹿开始,按照编号顺序从小到大进行游戏,绕着圆桌不断循环。
游戏可能会循环进行多轮,直到场上仅剩下最后一只长脖子鹿时,游戏结束。
给出 \(P_0\) 和 \(n\),询问 \(k\) 号长脖子鹿最终成为唯一幸存者的概率 \(P_k\)。
输入输出格式
输入格式:
仅一行三个数,\(P_0,n,k\)。
输出格式:
一个浮点数 \(P_k\),误差应该小于 \(10^{-8}\)。(请保留更多位数的小数)
输入输出样例
输入样例#1:
0.5 2 1
输出样例#1:
0.33333333
输入样例#2:
0.5 2 2
输出样例#2:
0.66666667
输入样例#3:
0.5 3 1
输出样例#3:
0.23809524
输入样例#4:
0.5 3 2
输出样例#4:
0.28571429
说明
对于 \(10\%\) 的数据,\(n\le 100\)。
对于 \(30\%\) 的数据,\(n\le 500\)。
对于另外 \(20\%\) 的数据,\(k=n\)。
对于 \(100\%\) 的数据,\(1\le k\le n\le 10^4,0\le P_0\le 1\)。
题解
首先需要推出DP/递推方程,然后考虑进一步的优化。因为本题有阶段性,姑且称之为DP。
每次枪会对准一个人,这个人有 \(P_0\) 的概率挂掉,此时进入 \(n-1\) 个人的状态。
考虑到枪打人是轮流进行的,先后顺序和位次顺序都是有影响的。因此我们设 \(f[i][j]\) 表示当剩下 \(i\) 个人时,令枪对准的人是第一个人,第 \(j\) 个人作为最后一个人存活下来的概率。
“当前的”第一个人有 \(P_0\) 的概率挂掉。这之后,总人数从 \(i\) 变成了 \(i-1\),而枪会指向原来第二个人,那么原来的 \(f[i][j]\) 在这样的条件下存活的概率是 \(f[i-1][j-1]\)。记为 \(P_0f[i-1][j-1]\)。
注:条件指条件概率。
在 \(1-P_0\) 的概率下,当前的第一个人不会挂掉,那么总人数不变,枪会指向原来的第二个人,那么第 \(j\) 个人就变成了第 \(j-1\) 个人,原来的 \(f[i][j]\) 在这样的条件下存活的概率是 \(f[i][j-1]\),记为 \((1-P_0)f[i][j-1]\)。
因此有
\]
这样由于每次在前一个大阶段有了所有的 \(f[i-1]\),就有了 \(f[i][j],1\le j\le i\) 的 \(i-1\) 个方程。根据逻辑关系我们知道 \(\sum_{j=1}^if[i][j]=1\),把这个当作第 \(i\) 个方程,这一组 \(f[i]\)就可以解了。
但是高斯消元是 \(O(n^3)\) 的,对于每一行都做,那就是 \(O(n^4)\) 的。实际上每一行可以做到线性。
由于 \(P_0f[i-1][j-1]\) 已知,我们把这个数设为常数 \(d_j\),则方程为
\]
此时可以通过这个式子减小第二维的 \(j\),上面有个式子是
\]
把这个式子所有的 \(j\) 都通过上面的方程迭代为 \(f[i][1]\),方程的形式就变为了 \(a\cdot f[i][1]+b=1\) 的形式,\(a,b\) 都是常数,\(f[i][1]\) 就被解出来了,再通过方程递推即可。
=&f[i][1]&+&d_2+(1-P_0)f[i][1]&+&\cdots+d_i+(1-P_0)f[i][i-1]
\end{aligned}
\]
针对这个式子,从后往前递归处理就可以得到 \(f[i][1]\) 的系数和常数项了。(实际上从前往后循环也可以,递归更好理解)
注意当 \(P_0=0\) 时,当且仅当 \(n=1\) 有 \(P_1=1\),其余情况下都不可能成为唯一幸存者,需要特判。
时间复杂度 \(O(n^2)\)。
Code:
#include<cstdio>
#include<cstring>
#define db double
db f[10010],d[10010],tmp,sum,p;
db a,b;
//a代表 f(x-1) 中 f1 的系数 b 代表 f(x-1) 的常数项
void calc(int x)
{
if(x==1)
{
a=1;
tmp=1;
b=0;
return;
}
calc(x-1);
//tmp 代表已经积累的 f1 的系数 sum 代表常数项
tmp+=(1-p)*a;
sum+=p*d[x]+(1-p)*b;
a=(1-p)*a;
b=p*d[x]+(1-p)*b;
}
int main()
{
int n,m;
scanf("%lf%d%d",&p,&n,&m);
if(p==0)
{
puts(n>1?"0":"1");
return 0;
}
f[1]=1;
d[2]=1;
for(int i=2;i<=n;++i)
{
tmp=0.0,sum=0.0;
calc(i);
f[1]=(1-sum)/tmp;
for(int j=2;j<=i;++j)
f[j]=p*d[j]+(1-p)*f[j-1];
for(int j=2;j<=i+1;++j)
d[j]=f[j-1];
}
printf("%.10lf\n",f[m]);
return 0;
}
洛谷 P5249 [LnOI2019]加特林轮盘赌 题解【概率期望】【DP】的更多相关文章
- 洛谷 P5249 - [LnOI2019]加特林轮盘赌(期望 dp+高斯消元)
题面传送门 期望真 nm 有意思,所以蒟蒻又来颓期望辣 先特判掉 \(P_0=0\) 的情况,下面假设 \(P_0\ne 0\). 首先注意到我们每次将加特林对准一个人,如果这个人被毙掉了,那么相当于 ...
- 【洛谷3239_BZOJ4008】[HNOI2015] 亚瑟王(期望 DP)
题目: 洛谷 3239 分析: 卡牌造成的伤害是互相独立的,所以 \(ans=\sum f_i\cdot d_i\) ,其中 \(f_i\) 表示第 \(i\) 张牌 在整局游戏中 发动技能的概率.那 ...
- 【洛谷1654/BZOJ4318】OSU!(期望DP)
题目: 洛谷1654 分析: 本人数学菜得要命,这题看了一整天才看明白-- 先说说什么是"期望".不太严谨地说,若离散型随机变量(可以看作"事件")\(X\)取 ...
- 题解——洛谷P2734 游戏A Game 题解(区间DP)
题面 题目背景 有如下一个双人游戏:N(2 <= N <= 100)个正整数的序列放在一个游戏平台上,游戏由玩家1开始,两人轮流从序列的任意一端取一个数,取数后该数字被去掉并累加到本玩家的 ...
- 洛谷P2365/5785 任务安排 题解 斜率优化DP
任务安排1(小数据):https://www.luogu.com.cn/problem/P2365 任务安排2(大数据):https://www.luogu.com.cn/problem/P5785 ...
- 洛谷P3211 [HNOI2011]XOR和路径(期望dp+高斯消元)
传送门 高斯消元还是一如既往的难打……板子都背不来……Kelin大佬太强啦 不知道大佬们是怎么发现可以按位考虑贡献,求出每一位是$1$的概率 然后设$f[u]$表示$u->n$的路径上这一位为$ ...
- 洛谷4206/NOI2005T4 聪聪和可可 期望DP+记忆化搜索
题意:给出n个点m条边的无向图,两个主角聪聪和可可开始分别在S点和T点.聪聪想吃掉可可,每次由匆匆先行动后来可可行动.聪聪的行动是选他到可可的最短路上的点走最多两步(如果最短路有几条就选编号最小的走) ...
- 【bzoj4832】[Lydsy2017年4月月赛]抵制克苏恩 概率期望dp
题目描述 你分别有a.b.c个血量为1.2.3的奴隶主,假设英雄血量无限,问:如果对面下出一个K点攻击力的克苏恩,你的英雄期望会受到到多少伤害. 输入 输入包含多局游戏. 第一行包含一个整数 T (T ...
- 【loj6191】「美团 CodeM 复赛」配对游戏 概率期望dp
题目描述 n次向一个栈中加入0或1中随机1个,如果一次加入0时栈顶元素为1,则将这两个元素弹栈.问最终栈中元素个数的期望是多少. 输入 一行一个正整数 n . 输出 一行一个实数,表示期望剩下的人数, ...
随机推荐
- 白盒测试实践项目(day1)
由于近期各种考试逼近,我们小组白盒测试实践项目进度有些慢,在任务决定后的两天里,我们小组各个成员的进度完成不一. 胡俊辉熟悉了怎么使用Junit对部分代码的测试,初步掌握了Junit的简单使用. 汪鸿 ...
- 6、Semantic-UI之动画按钮样式
6.1 动画按钮样式 在Semantic-UI中提供了三种动画样按钮式表,分别为: 左右移动 上下移动 淡入淡出 在实际开发中,很少使用这种动画按钮,根据实际情况使用,强制使用到页面中反而不太适合 ...
- C++ 调用C++写的函数库的2种方法之一(显式调用)
一:创建C++ DLL类库,名称:Dll1 1.Dll.h _declspec(dllimport) int add(int a, int b); 2.Dll.cpp // Dll.cpp : 定义 ...
- Maven项目常见错误
一.Cannot change version of project facet Dynamic Web Module to 3.0. 和 One or more constraints have n ...
- 文字编码ASCII,GB2312,GBK,GB18030,UNICODE,UCS,UTF的解析
众所周知,一个文字从输入到显示到存储是有一个固定过程的,其过程为:输入码(根据输入法不同而不同)→机内码(根据语言环境不同而不同,不同的系统语言编码也不一样)→字型码(根据不同的字体而不同)→存储码( ...
- Linq限定操作之All,Any,Contains源码分析
Linq限定操作之All,Any,Contains源码分析 linq的限定操作 常见的限定操作: All,Any,Contains 一:All 1. 解释: 确定序列中的所有元素是否满足条件. 从字面 ...
- Nhibernate 存储过程获取返回值
写在前面:因为项目使用ssh.net所以做着做着要调用存储过程,而且是有返回值的,按照以前的做法直接在参数里指定下就可以获取,但是在nhibernate里调用就有点陌生了,百度一下得出的结果有两种:第 ...
- PMBOK项目管理思维导图梳理
采用思维导图的形式来展示项目管理的五大过程组.九大知识领域,能更好的展示框架结构,便于理解.分析. 下图为思维导图化制的项目管理要素:灰色为启动过程组.白色为规划过程组.紫色为执行过程组.蓝色为监控过 ...
- [VSTO] warning CS0467 解决方案
warning CS0467: Ambiguity between method 'Microsoft.Office.Interop.Word._Document.Close(ref object, ...
- SOLR企业搜索平台 二 (分词安装)
标签:linux lucene 分词 solr 全文检索 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://3961409.blog ...