【BZOJ 2318】 2318: Spoj4060 game with probability Problem(概率DP)
2318: Spoj4060 game with probability Problem
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 371 Solved: 173Description
Alice和Bob在玩一个游戏。有n个石子在这里,Alice和Bob轮流投掷硬币,如果正面朝上,则从n个石子中取出一个石子,否则不做任何事。取到最后一颗石子的人胜利。Alice在投掷硬币时有p的概率投掷出他想投的一面,同样,Bob有q的概率投掷出他相投的一面。
现在Alice先手投掷硬币,假设他们都想赢得游戏,问你Alice胜利的概率为多少。
Input
第一行一个正整数t,表示数据组数。
对于每组数据,一行三个数n,p,q。
Output
对于每组数据输出一行一个实数,表示Alice胜利的概率,保留6位小数。
Sample Input
11 0.5 0.5
Sample Output
0.666667HINT
数据范围:
1<=t<=50
0.5<=p,q<=0.99999999
对于100%的数据 1<=n<=99999999
Source
【分析】
这种题的特点是转移成环,一般来说要消元。不过这题转台转移量少,可以手动消元。
打了两种打法:
1、【我自己的方法】
f[i][0]表示0作为先手,面对i个棋子,0获胜概率。
f[i][1]表示1作为先手,面对i个棋子,1获胜概率。
f[i][0]=1-p*min(f[i][1],f[i-1][1])-(1-p)*max(f[i][1],f[i-1][1])
f[i][1]=1-q*min(f[i][0],f[i-1][0])-(1-q)*max(f[i][0],f[i-1][0])
但是这里有min和max,不能直接移项。共有四种情况,每种情况都算一下,然后判断这个min和max是否成立。
【其实会不会有多解sm的呢?我也不清楚,但是答案肯定是符合的。。至于为什么只有答案符合,我也不会证明。但是这样是可以过的。
【其实主要是这样判断,最值里面有不确定因素,其实判断f[i-1][0]和1-f[i-1][1]也是可以的,就不用枚举4种情况那么麻烦了
代码:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define Maxn 1100 double f[Maxn][]; int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
double p,q;
scanf("%d%lf%lf",&n,&p,&q);
n=min(n,);
f[][]=f[][]=;
for(int i=;i<=n;i++)
{
double A0=f[i-][],A1=f[i-][],P,Q;
//x0=1-P*x1-(1-P)*A1
//x1=1-Q*x0-(1-Q)*A0
P=p,Q=q;
f[i][]=(-P+P*(-Q)*A0-(-P)*A1)/(-P*Q);
f[i][]=(-Q+Q*(-P)*A1-(-Q)*A0)/(-P*Q);
if(f[i][]<=A1&&f[i][]<=A0) continue;
P=p,Q=-q;
f[i][]=(-P+P*(-Q)*A0-(-P)*A1)/(-P*Q);
f[i][]=(-Q+Q*(-P)*A1-(-Q)*A0)/(-P*Q);
if(f[i][]<=A1&&f[i][]>=A0) continue;
P=-p,Q=q;
f[i][]=(-P+P*(-Q)*A0-(-P)*A1)/(-P*Q);
f[i][]=(-Q+Q*(-P)*A1-(-Q)*A0)/(-P*Q);
if(f[i][]>=A1&&f[i][]<=A0) continue;
P=-p,Q=-q;
f[i][]=(-P+P*(-Q)*A0-(-P)*A1)/(-P*Q);
f[i][]=(-Q+Q*(-P)*A1-(-Q)*A0)/(-P*Q);
}
printf("%.6lf\n",f[n][]);
}
return ;
}
2、第二种方法是看别人的,代码量比我少一点。
但是我一般不会这样表示的说。
f[i][0]表示0面对i,0获胜概率。f[i][1]表示1面对i,0获胜概率。
那么当f[i-1][0]>f[i-1][1],当面对i时,0肯定想拿石子,1肯定不想。
反之不说了。
f[i][0]=p*f[i-1][0]+(1-p)*f[i][1]
f[i][1]=q*f[i-1][1]+(1-q)*f[i][0]
反之
f[i][0]=(1-p)*f[i-1][0]+p*f[i][1]
f[i][1]=(1-q)*f[i-1][1]+q*f[i][0]
移项消元即可。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define Maxn 1100 double f[Maxn][]; int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
double p,q;
scanf("%d%lf%lf",&n,&p,&q);
n=min(n,);
f[][]=;f[][]=;
for(int i=;i<=n;i++)
{
double A0=f[i-][],A1=f[i-][],P,Q;
if(A0<=A1) P=-p,Q=-q;
else P=p,Q=q;
f[i][]=(A1*(-P)+A0*(-Q)*P)/(-P*Q);
f[i][]=(A0*(-Q)+A1*(-P)*Q)/(-P*Q);
}
printf("%.6lf\n",f[n][]);
}
return ;
}
2017-04-22 10:17:55
【BZOJ 2318】 2318: Spoj4060 game with probability Problem(概率DP)的更多相关文章
- BZOJ 2318: Spoj4060 game with probability Problem( 概率dp )
概率dp... http://blog.csdn.net/Vmurder/article/details/46467899 ( from : [辗转山河弋流歌 by 空灰冰魂] ) 这个讲得很好 , ...
- BZOJ 2318: Spoj4060 game with probability Problem (概率dp)(博弈论)
2318: Spoj4060 game with probability Problem Description Alice和Bob在玩一个游戏.有n个石子在这里,Alice和Bob轮流投掷硬币,如果 ...
- 【bzoj2318】Spoj4060 game with probability Problem 概率dp
题目描述 Alice和Bob在玩一个游戏.有n个石子在这里,Alice和Bob轮流投掷硬币,如果正面朝上,则从n个石子中取出一个石子,否则不做任何事.取到最后一颗石子的人胜利.Alice在投掷硬币时有 ...
- 【BZOJ2318】Spoj4060 game with probability Problem 概率
[BZOJ2318]Spoj4060 game with probability Problem Description Alice和Bob在玩一个游戏.有n个石子在这里,Alice和Bob轮流投掷硬 ...
- 【BZOJ2318】【spoj4060】game with probability Problem 概率DP
链接: #include <stdio.h> int main() { puts("转载请注明出处[辗转山河弋流歌 by 空灰冰魂]谢谢"); puts("网 ...
- Bzoj 2318 Spoj4060 game with probability Problem
2318: Spoj4060 game with probability Problem Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 524 Sol ...
- 2318: Spoj4060 game with probability Problem
2318: Spoj4060 game with probability Problem Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 356 Sol ...
- BZOJ2318: Spoj4060 game with probability Problem
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #i ...
- 【bzoj2318】Spoj4060 game with probability Problem
题目描述 Alice和Bob在玩一个游戏.有n个石子在这里,Alice和Bob轮流投掷硬币,如果正面朝上,则从n个石子中取出一个石子,否则不做任何事.取到最后一颗石子的人胜利.Alice在投掷硬币时有 ...
随机推荐
- Linux内核触摸屏驱动--多点触摸 【转】
转自:http://blog.chinaunix.net/uid-24227137-id-3127126.html 简介 为了使用功能强大的多点触控设备,就需要一种方案去上报用户层所需的详细的手指 ...
- ClientDataset 三层 var and out arguments must match parameter
将Delphi升级到10.1.2后,从客户端传ClientDataset的Delta数据到服务端程序时,出现var and out arguments must match parameter错 ...
- 服务发现 consul cluster 的搭建
consul cluster setup 介绍和指南: consul用于服务发现.当底层服务发生变化时,能及时更新正确的mysql服务IP. 并提供给业务查询.但需要自行编写脚本,监测数据库状态和切断 ...
- Django BoundField
一.BoundField from django.forms.boundfield import BoundField BoundField是一个将字段添加数据的一个类,给对应的form字段封装上数据 ...
- KVM和远程管理工具virt-manager
kvm在server端的部署(针对rhel6系统,可以构建本地更新源) 注意:如果只是安装管理工具,可以试试直接执行8步骤 1.对服务器实行kvm虚拟化首先需要确认服务器的物理硬件是否支持 cat / ...
- Codeforces 552C Vanya and Scales(进制转换+思维)
题目链接:http://codeforces.com/problemset/problem/552/C 题目大意:有101个砝码重量为w^0,w^1,....,w^100和一个重量为m的物体,问能否在 ...
- the server ssl certificate failed to verify
很久没上传项目之后,远程端断开联系 如果是git,就git clone,重新把项目拉下来. svn的话,就svn ls,拉下项目.
- c++实现二叉树的非递归创建以及非递归先序、中序、后序遍历
二叉树的创建 思路:数组中从上到下依次放着二叉树中的元素,使用递归很容易实现,那么这里使用容器来存放之前的状态实现循环创建二叉树. TreeNode* createTree(int *arr, int ...
- 通过构造系统服务分发实现拦截&过滤 (仿360游戏保险箱)
想写这个程序主要是因为看了KSSD的一篇帖子,http://bbs.pediy.com/showthread.php?t=108378 讲 的是360保险箱保护游戏账号的原理,实际上就是对各种请求的拦 ...
- java 基础类库之 SysFun
/** * 将对象转为字符串:为空,则返回空字符串:而不是"null" * @param pObj 为空,则返回空字符串 * @return */ public static St ...