ZOJ3329之经典概率DP
One Person Game
Time Limit: 1 Second Memory Limit: 32768 KB Special Judge
There is a very simple and interesting one-person game. You have 3 dice, namely Die1, Die2 and Die3. Die1 has K1 faces. Die2 has K2 faces. Die3 has K3 faces.
All the dice are fair dice, so the probability of rolling each value, 1 to K1, K2, K3 is exactly 1 / K1, 1 / K2 and 1 / K3. You have a counter,
and the game is played as follow:
- Set the counter to 0 at first.
- Roll the 3 dice simultaneously. If the up-facing number of Die1 is a, the up-facing number of Die2 is b and the up-facing number of Die3 is c, set the counter to 0. Otherwise,
add the counter by the total value of the 3 up-facing numbers. - If the counter's number is still not greater than n, go to step 2. Otherwise the game is ended.
Calculate the expectation of the number of times that you cast dice before the end of the game.
Input
There are multiple test cases. The first line of input is an integer T (0 < T <= 300) indicating the number of test cases. Then T test cases follow. Each test
case is a line contains 7 non-negative integers n, K1, K2, K3, a, b, c (0 <= n <= 500, 1 < K1, K2, K3 <=
6, 1 <= a <= K1, 1 <= b <= K2, 1 <= c <= K3).
Output
For each test case, output the answer in a single line. A relative error of 1e-8 will be accepted.
Sample Input
2
0 2 2 2 1 1 1
0 6 6 6 1 1 1
Sample Output
1.142857142857143
1.004651162790698
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3754
/*题意:
有三个骰子,分别有k1,k2,k3个面。
每次掷骰子,如果三个面分别为a,b,c则分数置0,否则加上三个骰子的分数之和。
当分数大于n时结束。求游戏的期望步数。初始分数为0 分析:
如果dp[i]表示拥有分数i到游戏结束的期望步数
则
(1):dp[i]=SUM(p[k]*dp[i+k])+p[0]*dp[0]+1;//p[k]表示添加分数为k的概率,p[0]表示分数变为0的概率
假定
(2):dp[i]=A[i]*dp[0]+B[i];
则
(3):dp[i+k]=A[i+k]*dp[0]+B[i+k];
将(3)代入(1)得:
(4):dp[i]=(SUM(p[k]*A[i+k])+p[0])*dp[0]+SUM(p[k]*B[i+k])+1;
将4与2做比較得:
A[i]=(SUM(p[k]*A[i+k])+p[0]);
B[i]=SUM(p[k]*B[i+k])+1;
当i+k>n时A[i+k]=B[i+k]=0可知
所以dp[0]=B[0]/(1-A[0])可求出
*************************************************************************
总结下这类概率DP:
既DP[i]可能由DP[i+k]和DP[i+j]须要求的比方DP[0]决定
相当于概率一直递推下去会回到原点
比方
(1):DP[i]=a*DP[i+k]+b*DP[0]+d*DP[i+j]+c;
可是DP[i+k]和DP[0]都是未知
这时候依据DP[i]的方程式如果一个方程式:
比方:
(2):DP[i]=A[i]*DP[i+k]+B[i]*DP[0]+C[i];
由于要求DP[0],所以当i=0的时候可是A[0],B[0],C[0]未知
对照(1)和(2)的区别
这时候对照(1)和(2)发现两者之间的区别在于DP[i+j]
所以依据(2)求DP[i+j]然后代入(1)消除然后对照(2)就能够得到A[i],B[i],C[i]
然后视详细情况依据A[i],B[i],C[i]求得A[0],B[0],C[0]继而求DP[0]
请看这题:http://acm.hdu.edu.cn/showproblem.php?pid=4035
*************************************************************************
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <queue>
#include <algorithm>
#include <map>
#include <cmath>
#include <iomanip>
#define INF 99999999
typedef long long LL;
using namespace std; const int MAX=500+10;
int n,k1,k2,k3,a,b,c;
double p[20],A[MAX+10],B[MAX+10]; void dfs(int i){//求A[i],B[i]
if(A[i]>0)return;
if(i>n){A[i]=B[i]=0;return;}
A[i]=p[0],B[i]=1;
for(int k=3;k<=k1+k2+k3;++k){
dfs(i+k);
A[i]+=p[k]*A[i+k];
B[i]+=p[k]*B[i+k];
}
} int main(){
int t;
scanf("%d",&t);
while(t--){
memset(p,0,sizeof p);
scanf("%d%d%d%d%d%d%d",&n,&k1,&k2,&k3,&a,&b,&c);
p[0]=1.0/(k1*k2*k3);
for(int i=1;i<=k1;++i){
for(int j=1;j<=k2;++j){
for(int k=1;k<=k3;++k){
p[i+j+k]+=p[0];//求i+j+k的概率
}
}
}
p[a+b+c]-=p[0];//a+b+c的分数不能等于a,b,c,所以须要减去
memset(A,0,sizeof A);
memset(B,0,sizeof B);
dfs(0);
/*memset(A,0,sizeof A);
memset(B,0,sizeof B);
for(int i=n;i>=0;--i){
A[i]=p[0],B[i]=1;
for(int k=3;k<=k1+k2+k3;++k){
A[i]+=p[k]*A[i+k];
B[i]+=p[k]*B[i+k];
}
}*/
printf("%.15f\n",B[0]/(1-A[0]));
}
return 0;
}
ZOJ3329之经典概率DP的更多相关文章
- ZOJ 3329 One Person Game (经典概率dp+有环方程求解)
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3329 题意:现在有三个骰子,分别有k1,k2和k3面,面上的点就是1~ki ...
- poj 2096 Collecting Bugs 概率dp 入门经典 难度:1
Collecting Bugs Time Limit: 10000MS Memory Limit: 64000K Total Submissions: 2745 Accepted: 1345 ...
- 动态规划之经典数学期望和概率DP
起因:在一场训练赛上.有这么一题没做出来. 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6829 题目大意:有三个人,他们分别有\(X,Y,Z\)块钱 ...
- [转]概率DP总结 by kuangbin
概率类题目一直比较弱,准备把kuangbin大师傅总结的这篇题刷一下! 我把下面的代码换成了自己的代码! 原文地址:http://www.cnblogs.com/kuangbin/archive/20 ...
- 2018.09.27 bzoj3029: 守卫者的挑战(概率dp)
传送门 概率dp经典题目. 直接f[i][j][k]f[i][j][k]f[i][j][k]表示当前是第i次挑战,已经胜利了j次,目前的背包剩余空间是k. 然后用前面的转移后面的就行了. 注意第三维可 ...
- 2018.09.24 bzoj1867: [Noi1999]钉子和小球(概率dp)
传送门 概率dp经典题. 如果当前位置(i,j)(i,j)(i,j)有钉子,那么掉到(i+1,j),(i+1,j+1)(i+1,j),(i+1,j+1)(i+1,j),(i+1,j+1)的概率都是1/ ...
- 【整理】简单的数学期望和概率DP
数学期望 P=Σ每一种状态*对应的概率. 因为不可能枚举完所有的状态,有时也不可能枚举完,比如抛硬币,有可能一直是正面,etc.在没有接触数学期望时看到数学期望的题可能会觉得很阔怕(因为我高中就是这么 ...
- 概率dp集合
bzoj1076 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物,每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝物以后 ...
- DP专题之概率DP
注意:在概率DP中求期望要逆着推,求概率要正着推 概率DP求期望: 链接: http://acm.hdu.edu.cn/showproblem.php?pid=4405 dp[ i ]表示从i点走到n ...
随机推荐
- Qt经典出错信息之”Basic XLib functionality test failed!”
解决方法: 此完整出错信息是在./configure阶段Basic XLib functionality test failed!You might need to modify the includ ...
- delegate 中的BeginInvoke和EndInvoke方法
开发语言:C#3.0 IDE:Visual Studio 2008 一.C#线程概述 在操作系统中一个进程至少要包含一个线程,然后,在某些时候需要在同一个进程中同时执行多项任务,或是为了提供程序的性能 ...
- 搜索所有的路径-矩阵运算-暴力-ACM
给定一个n*n整数矩阵,定义对I行的SHIFT操作( 0 <= i < n ),是将第I行所有元素都右移一位,最右边的移到最左边. 你可以对任意行进行任意次SHIFT操作,使得: max0 ...
- 浏览器JS报错Uncaught RangeError: Maximum call stack size exceeded?
JavaScript错误:Uncaught RangeError: Maximum call stack size exceeded 堆栈溢出 原因:有小类到大类的递归查询导致溢出 解决方法思想: A ...
- php基于数组的分页实现
关于数组的分页函数,用数组进行分页的好处是可以方便的进行联合多表查询,只需要将查询的结果放在数组中就可以了以下是数组分页的函数,函数page_array用于数组的分页,函数show_array用于分页 ...
- js touch触屏原理分析
之前我们做过许多触屏的特效,那么,今天,我们来分析下js的触屏原理.事实上,大家百度一下js touch基本上可以找到这文章“指尖下的js ——多触式web前端开发之一:对于Touch的处理”,我想这 ...
- 模块化编程AMD&CommonJS
为什么要模块化编程 如果JS也可以像类似python,Java使用import,引入我们想要的模块,想要什么模块,就加载什么模块,可以给前端编程带来更多的便捷,结构更加清晰明了.但是,这样做有一个前提 ...
- elasticsearch 性能优化
#系统默认的最大打开文件数的限制 vi /etc/security/limits.conf * - nproc 50240 * - ...
- 转:使用xhprof进行线上PHP性能追踪及分析
原文来自于:http://avnpc.com/pages/profiler-php-performance-online-by-xhprof 原创作者:AlloVince 之前一直使用基于Xdebug ...
- Biathlon Track
Codeforces Round #242 (Div. 2) D:http://codeforces.com/contest/424/problem/D 题意:给你一个n*m的矩阵,每个格子上面有个数 ...