【bzoj2318】game with probability
Description
Alice和Bob在玩一个游戏。有n个石子在这里,Alice和Bob轮流投掷硬币,如果正面朝上,则从n个石子中取出一个石子,否则不做任何事。取到最后一颗石子的人胜利。Alice在投掷硬币时有p的概率投掷出他想投的一面,同样,Bob有q的概率投掷出他相投的一面。
现在Alice先手投掷硬币,假设他们都想赢得游戏,问你Alice胜利的概率为多少。
答案保留6位小数
数据范围$1<=t<=50,0.5<=q,p<=0.99999999,1<=n<=99999999 $
Solution
额这题也是权限题放一下题面好了
这个的话一开始自己想多了。。老觉得会不会说为了最优决策所以Alice为了有更大的概率得到想要的结果而故意想相反的结果之类的。。
emmm后来发现Alice和Bob根本不知道概率是多少所以根本不存在这个问题qwq
那所以我们可以考虑直接两个数组大力dp
记\(f[i]\)为\(i\)个石子的情况下Alice(先手)的胜率,\(g[i]\)为\(i\)个石子的情况下Bob(后手)的胜率
那么我们可以得到这样的两种转移:
1、如果说这一步拿走石子会更优,那么有:
f[i]=p*g[i-1]+(1-p)*g[i]\\
g[i]=q*f[i-1]+(1-q)*f[i]\\
\end{aligned}
\]
具体一点的话以\(f[i]\)的计算为例,前半部分是第一步Alice拿了,然后局面就变成了有\(i-1\)个石头并且是后手,所以乘的是\(g[i-1]\),然后后半部分就是第一步Alice没有拿,那就变成了有\(i\)个石头并且是后手,所以是乘上\(g[i]\),第二条式子同理就不赘述了
然后我们大力化一下可以将这两条式子变成用\(f[i-1]\)和\(g[i-1]\)推出\(f[i]\)和\(g[i]\)的式子
(用\(g[i]\)的表达式把第一条式子里面的\(g[i]\)换掉就好了,第二条式子的处理类似):
f[i]&=\frac{p*g[i-1]+(1-p)*q*f[i-1])}{1-(1-p)(1-q)}\\
\\
g[i]&=\frac{q*f[i-1]+(1-q)*p*g[i-1])}{1-(1-p)(1-q)}\\
\end{aligned}
\]
2、如果说这一步不拿走石子会更优,那么有:
f[i]=p*g[i]+(1-p)*g[i-1]\\
g[i]=q*f[i]+(1-q)*f[i-1]\\
\end{aligned}
\]
具体含义什么的跟上面的差不多
仔细看一下emmmm那好像直接就是\(p\)变成了\(1-p\)然后\(q\)变成了\(1-q\)而已。。所以转移的时候判断一下就好了
那现在就是怎么判断是拿更优还是不拿更优,仔细思考一下这个拿和不拿其实影响到的是接下来局面的先手后手问题,所以我们就比较一下\(i-1\)个石子的情况下是先手的胜率更大还是后手的胜率更大就好了,也就是直接比较一下\(f[i-1]\)和\(g[i-1]\)即可
然后还有一个东西就是。。推大概到\(1000\)之后(额或者更小一点也行qwq貌似只推到\(50\)也。。问题不大?没有交过qwq)在精度范围内就不会有变化了,所以大力“近似”一下每次只用推到\(1000\),这样就不会有超时的问题啦(算是一个套路吗。。?)
代码大概长这个样子:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=1001;
double f[N],g[N];
double p,q,P,Q;
int n,m,t;
int main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
#endif
scanf("%d",&t);
for (int o=1;o<=t;++o){
scanf("%d%lf%lf",&n,&P,&Q);
n=min(n,1000);
f[0]=0; g[0]=1;
for (int i=1;i<=n;++i){
if (f[i-1]>g[i-1]) p=1.0-P,q=1.0-Q;
else p=P,q=Q;
f[i]=(p*g[i-1]+(1-p)*q*f[i-1])/(1-(1-p)*(1-q));
g[i]=(q*f[i-1]+(1-q)*p*g[i-1])/(1-(1-p)*(1-q));
}
printf("%.6lf\n",f[n]);
}
}
【bzoj2318】game with probability的更多相关文章
- 【BZOJ2318】Spoj4060 game with probability Problem 概率
[BZOJ2318]Spoj4060 game with probability Problem Description Alice和Bob在玩一个游戏.有n个石子在这里,Alice和Bob轮流投掷硬 ...
- 【leetcode】688. Knight Probability in Chessboard
题目如下: On an NxN chessboard, a knight starts at the r-th row and c-th column and attempts to make exa ...
- 【bzoj2318】Spoj4060 game with probability Problem
题目描述 Alice和Bob在玩一个游戏.有n个石子在这里,Alice和Bob轮流投掷硬币,如果正面朝上,则从n个石子中取出一个石子,否则不做任何事.取到最后一颗石子的人胜利.Alice在投掷硬币时有 ...
- 【BZOJ2318】【spoj4060】game with probability Problem 概率DP
链接: #include <stdio.h> int main() { puts("转载请注明出处[辗转山河弋流歌 by 空灰冰魂]谢谢"); puts("网 ...
- 【bzoj2318】Spoj4060 game with probability Problem 概率dp
题目描述 Alice和Bob在玩一个游戏.有n个石子在这里,Alice和Bob轮流投掷硬币,如果正面朝上,则从n个石子中取出一个石子,否则不做任何事.取到最后一颗石子的人胜利.Alice在投掷硬币时有 ...
- 【LeetCode】688. Knight Probability in Chessboard 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址:https://leetcode.com/problems/knight-pr ...
- 【概率论】2-1:条件概率(Conditional Probability)
title: [概率论]2-1:条件概率(Conditional Probability) categories: Mathematic Probability keywords: Condition ...
- 【概率论】1-1:概率定义(Definition of Probability)
title: [概率论]1-1:概率定义(Definition of Probability) categories: Mathematic Probability keywords: Sample ...
- 【原创】开源Math.NET基础数学类库使用(12)C#随机数扩展方法
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 开源Math.NET基础数学类库使用总目录:[目录]开源Math.NET基础数学类库使用总目录 前言 ...
随机推荐
- 关于scrum敏捷测试
关于scrum的一些定义 敏捷软件开发方法是一种把新增功能通过较小的循环逐步迭代添加到项目中(的项目管理方法),工作是由自我组织的团队以高效合作的方式拥抱和适应变化来保证客户需求被真正满足的方式来完成 ...
- cinder的组件
跟nova相似,cinder也有很多组件,每个组件负责各自的业务,然后共同协作完成volume的管理.组件之间的通信方式与nova个组件之间的通信方式相同,都是通过消息队列进行通信. cinder-a ...
- 写一个脚本批量转换项目中GB2312编码的文件为UTF-8编码
#!/bin/bash convert_file() { for file in `find .` do if [[ -f $file ]] then if [[ ${file##*.} == lua ...
- linux云主机小技巧
微信服务器安装 安装库 python 3.5环境下 pip安装web.py时 会报错 "no module named "utils" 等问题 更换命令为“pip ins ...
- Python Requests库简单入门
我对Python网络爬虫的学习主要是基于中国慕课网上嵩天老师的讲授,写博客的目的是为了更好触类旁通,并且作为学习笔记之后复习回顾. 1.引言 requests 库是一个简洁且简单的处理HTTP请求的第 ...
- 《JavaScript》JS中的常用方法attr(),splice()
1.jquery中用attr()方法来获取和设置元素属性,attr是attribute(属性)的缩写,在jQuery DOM操作中会经常用到attr(),attr()有4个表达式. attr(属性名) ...
- c# byte转docx
问题情境: docx文件放进resource中,再用程序读出来的时候是二进制数组. 解决办法: public string ByteConvertWord(byte[] data, string fi ...
- Right-BICEP 测试四则运算程序
测试方法: Right-BICEP 测试计划: 1.边界测试是否正确 2.负数表示是否实现 3.是否有乘除法 4.是否可以选择题目数量 5.是否有输出方式 6.是否有括号 7.是否有重复查询 ...
- 总结在Visual Studio Code运行node.js项目遇到的问题
一.cannot find module “lodash” 项目运行时出现以下错误: Error: Cannot find module 'lodash' at Function.Module._re ...
- Codeforces Beta Round #7 D. Palindrome Degree manacher算法+dp
题目链接: http://codeforces.com/problemset/problem/7/D D. Palindrome Degree time limit per test1 secondm ...