[LnOI2019]加特林轮盘赌(DP,概率期望)
[LnOI2019]加特林轮盘赌(DP,概率期望)
题解:
首先特判掉\(p=0/1\)的情况...
先考虑如果\(k=1\)怎么做到\(n^2\)的时间复杂度
设\(f[i]\)表示有\(i\)个人,\(k=1\)的时候幸存的概率
设\(g[i][j]\)表示\(i\)个人每个人挨一下恰好死\(j\)个人的概率
我们就可以列出转移方程:
\]
- 含义:枚举打了一圈后剩下多少人,乘\(1-p\)是因为要保证自己不死
把含有\(f[i]\)的项全部移到左边,化简得:
\]
于是我们就可以愉快地\(dp\)啦
数组\(g\)存不下来,\(dp\)的时候动态更新就好啦
如果\(k!=1\)怎么办呢?
我们可以把\(1\sim k-1\)的这些人先打一遍,对于每种剩下的人数分别计算答案,然后按照概率加起来就好了
\(double\)运算常数很大,比赛时一直\(TLE\)在\(65\)分,关于这个常数的问题有两种解决方法:
- 可以把所有数全部乘上一个\(2e9\)转化为\(long long\)进行运算,算完在除回来,缺点是精度较低,容易写错
- 直接把\(double\)换成\(longdouble\)就行了,不过稍微慢点
看了看排行榜,好像有\(O(n)\)的做法?
代码:
#include<map>
#include<set>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define qmax(x,y) (x=max(x,y))
#define qmin(x,y) (x=min(x,y))
#define mp(x,y) make_pair(x,y)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
inline int read(){
int ans=0,fh=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') fh=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
ans=ans*10+ch-'0',ch=getchar();
return ans*fh;
}
const ll maxn=1e4+100,w=2e9;
int n,k;
ll p,g[maxn],f[maxn],pp[maxn];
double php;
int main(){
// freopen("nh.in","r",stdin);
// freopen("zhy.out","w",stdout);
scanf("%lf%d%d",&php,&n,&k);
if(php==0){
printf(n==1?"1\n":"0\n");
return 0;
}
p=php*w;
int x=k-1;
f[1]=1*w,g[0]=w-p,g[1]=p;
if(x==1)
for(int j=0;j<=n;j++)
pp[j]=g[j];
for(int i=2;i<=n;i++){
int j;
for(j=1;j<i-3;j+=4){
f[i]+=f[j]*g[i-j]/w;
f[i]+=f[j+1]*g[i-j-1]/w;
f[i]+=f[j+2]*g[i-j-2]/w;
f[i]+=f[j+3]*g[i-j-3]/w;
}
for(;j<i;j++) f[i]+=f[j]*g[i-j]/w;
(f[i]*=w-p)/=w;
for(j=i;j>=4;j-=4){
g[j]=(g[j-1]*p+g[j]*(w-p))/w;
g[j-1]=(g[j-2]*p+g[j-1]*(w-p))/w;
g[j-2]=(g[j-3]*p+g[j-2]*(w-p))/w;
g[j-3]=(g[j-4]*p+g[j-3]*(w-p))/w;
}
for(;j;j--) g[j]=(g[j-1]*p+g[j]*(w-p))/w;
(g[0]*=w-p)/=w;
if(i==x)
for(int j=0;j<=n;j++)
pp[j]=g[j];
(f[i]*=w)/=w-g[0];
}
if(x==0){
printf("%.12lf\n",f[n]*1.0/w);
return 0;
}
double ans=0;
for(int i=0;i<=x;i++){
ans+=pp[i]*f[n-i]/w;
}
printf("%.12lf\n",ans*1.0/w);
return 0;
}
[LnOI2019]加特林轮盘赌(DP,概率期望)的更多相关文章
- 洛谷 P5249 [LnOI2019]加特林轮盘赌 题解【概率期望】【DP】
很有意思的题目. 题目背景 加特林轮盘赌是一个养生游戏. 题目描述 与俄罗斯轮盘赌等手枪的赌博不同的是,加特林轮盘赌的赌具是加特林. 加特林轮盘赌的规则很简单:在加特林的部分弹夹中填充子弹.游戏的参加 ...
- 洛谷 P5249 - [LnOI2019]加特林轮盘赌(期望 dp+高斯消元)
题面传送门 期望真 nm 有意思,所以蒟蒻又来颓期望辣 先特判掉 \(P_0=0\) 的情况,下面假设 \(P_0\ne 0\). 首先注意到我们每次将加特林对准一个人,如果这个人被毙掉了,那么相当于 ...
- Codeforces1097D. Makoto and a Blackboard(数论+dp+概率期望)
题目链接:传送门 题目大意: 给出一个整数n写在黑板上,每次操作会将黑板上的数(初始值为n)等概率随机替换成它的因子. 问k次操作之后,留在黑板上的数的期望. 要求结果对109+7取模,若结果不是整数 ...
- hdu-5781 ATM Mechine(dp+概率期望)
题目链接: ATM Mechine Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Other ...
- BZOJ3566:[SHOI2014]概率充电器(树形DP,概率期望)
Description 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品——概率充电器: “采用全新纳米级加工技术,实现元件与导线能否通电完全由真随机数决定!SHOI 概率充电器, ...
- hdu-5816 Hearthstone(状压dp+概率期望)
题目链接: Hearthstone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Other ...
- BZOJ4008:[HNOI2015]亚瑟王(DP,概率期望)
Description 小 K 不慎被 LL 邪教洗脑了,洗脑程度深到他甚至想要从亚瑟王邪教中脱坑. 他决定,在脱坑之前,最后再来打一盘亚瑟王.既然是最后一战,就一定要打得漂亮.众所周知,亚瑟王是一个 ...
- [LnOI2019]加特林轮盘赌
Luogu5249 轮流开枪打一个环上的人 , 每次\(p\)的概率打死 , \(p\)始终相同 , 从第\(1\)个人开始 , 求第\(k\)个人成为唯一幸存者的概率 \(19.3.30\) 官方题 ...
- 【BZOJ-1419】Red is good 概率期望DP
1419: Red is good Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 660 Solved: 257[Submit][Status][Di ...
随机推荐
- 【MVC model 验证失效 】【Unexpected token u in JSON at position 0】【jquery-plugin-validation】
问题描述:mvc model 调用jquery-plugin-validation 实现 前台的数据验证,时报错 Unexpected token u in JSON at position 0 很讨 ...
- 爬虫实战【13】获取自己的动态代理ip池
在爬取一些比较友好的网站时,仍然有可能因为单位时间内访问次数过多,使服务器认定为机器访问,导致访问失败或者被封.如果我们使用不同的ip来访问网站的话,就可以绕过服务器的重复验证,使服务器以为使不同的人 ...
- vue学习之旅:入门
首先利用脚手架vue cli搭建vue环境 引入 vue <script src="https://unpkg.com/vue/dist/vue.js"></sc ...
- cpp中文乱码
中文乱码 [root@test mediaStudio]# g++ testCgi.cpp [root@test mediaStudio]# ./a.out Content-type:text/htm ...
- IO流入门-第五章-FileWriter
FileWriter基本用法和方法示例 /* java.io.Writer java.io.OutputStreamWriter 转换流(字节输出流--->字符输出流) java.io.File ...
- screenX clientX pageX区别
screenX:鼠标位置相对于用户屏幕水平偏移量,而screenY也就是垂直方向的,此时的参照点也就是原点是屏幕的左上角. clientX:跟screenX相比就是将参照点改成了浏览器内容区域的左上角 ...
- python常用方法详解
1,讲序列分解为单独的变量 p=(4,5) x,y=p print(x,y) 如果在分解中想丢弃某些特定的值,可以采用_来进行 data=['A','B','c','d'] _,name,age,_= ...
- 配置 Docker 镜像下载的本地 mirror 服务
Docker registry 工具如今已经非常好的支持了 mirror 功能,使用它能够配置一个本地的 mirror 服务.将 pull 过的镜像 cache 在本地.这样其他主机再次 pull 的 ...
- 手势识别:GestureDetector
当用户触摸屏幕的时候,会产生许多手势,例如down,up,scroll,filing等等,我们知道View类有个View.OnTouchListener接口,通过重写他的onTouch(View v, ...
- Python基础教程-Dict和Set
Python的dict Python内置了字典:dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度. 比如,要根据同学的名字查找对应的 ...