ZOJ 3329 One Person Game [概率DP]
2015-11-29 18:06
609 查看
Description
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 K2faces. 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.
题意:
给出3个骰子,每个骰子的面数已知,并且对于每个骰子来说每一面出现的概率是相等的,当三个骰子分别为A,B,C时,计数器清0,否则加上三个骰子的点数和,问计数器大于N的期望投掷数。
解法:
假设DP[i]表示当前点数为i,达到大于N的状态的期望,那么DP[ >N ] =0
DP[I]=p*DP[0]+Σ (pk*dp[i+k]) +1
最后我们要解的便是dp[0],但是每一个dp[I]里面都含有了一个DP[0],我们需要把其前面的系数提取出来
设DP[I] = A[I] * DP[0] +B[I]
那么DP[0]=A[0]*DP[0]+B[0]
推出DP[0]=B[0]/(1-A[0])
A[I]=Σ(A[I+k]*pk)+p
B[I]=Σ(B[I+K]*pk)+1.0
代码:
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 K2faces. 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.
题意:
给出3个骰子,每个骰子的面数已知,并且对于每个骰子来说每一面出现的概率是相等的,当三个骰子分别为A,B,C时,计数器清0,否则加上三个骰子的点数和,问计数器大于N的期望投掷数。
解法:
假设DP[i]表示当前点数为i,达到大于N的状态的期望,那么DP[ >N ] =0
DP[I]=p*DP[0]+Σ (pk*dp[i+k]) +1
最后我们要解的便是dp[0],但是每一个dp[I]里面都含有了一个DP[0],我们需要把其前面的系数提取出来
设DP[I] = A[I] * DP[0] +B[I]
那么DP[0]=A[0]*DP[0]+B[0]
推出DP[0]=B[0]/(1-A[0])
A[I]=Σ(A[I+k]*pk)+p
B[I]=Σ(B[I+K]*pk)+1.0
代码:
#include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> #include<iostream> #include<stdlib.h> #include<set> #include<map> #include<queue> #include<vector> #include<bitset> #pragma comment(linker, "/STACK:1024000000,1024000000") template <class T> bool scanff(T &ret){ //Faster Input char c; int sgn; T bit=0.1; if(c=getchar(),c==EOF) return 0; while(c!='-'&&c!='.'&&(c<'0'||c>'9')) c=getchar(); sgn=(c=='-')?-1:1; ret=(c=='-')?0:(c-'0'); while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0'); if(c==' '||c=='\n'){ ret*=sgn; return 1; } while(c=getchar(),c>='0'&&c<='9') ret+=(c-'0')*bit,bit/=10; ret*=sgn; return 1; } #define inf 1073741823 #define llinf 4611686018427387903LL #define PI acos(-1.0) #define lth (th<<1) #define rth (th<<1|1) #define rep(i,a,b) for(int i=int(a);i<=int(b);i++) #define drep(i,a,b) for(int i=int(a);i>=int(b);i--) #define gson(i,root) for(int i=ptx[root];~i;i=ed[i].next) #define tdata int testnum;scanff(testnum);for(int cas=1;cas<=testnum;cas++) #define mem(x,val) memset(x,val,sizeof(x)) #define mkp(a,b) make_pair(a,b) #define findx(x) lower_bound(b+1,b+1+bn,x)-b #define pb(x) push_back(x) using namespace std; typedef long long ll; typedef pair<int,int> pii; double pa[1111]; double pb[1111]; int n,k1,k2,k3,a,b,c; double p[111],pe; int main(){ tdata{ scanff(n);scanff(k1);scanff(k2);scanff(k3); scanff(a);scanff(b);scanff(c); int tot=k1+k2+k3; mem(p,0); p[0]=1.0/double(k1*k2*k3); rep(i,1,k1) rep(j,1,k2) rep(k,1,k3){ if(i==a&&j==b&&k==c)continue; int sum=i+j+k; p[sum]+=1.0/double(k1*k2*k3); } mem(pa,0); mem(pb,0); drep(i,n,0){ rep(j,1,tot){ pa[i]+=pa[i+j]*p[j]; pb[i]+=pb[i+j]*p[j]; } pa[i]+=p[0]; pb[i]+=1.0; } double ans=pb[0]/(1.0-pa[0]); printf("%.15f\n",ans); } return 0; }
相关文章推荐
- leetcode Remove Duplicates from Sorted Array python
- android自定义View绘制天气温度曲线
- 控件与布局
- Android系统init.rc分析
- ORA-01012 not log on
- hdu 5586 Sum(dp+技巧)
- 2015/11/29 软件测试学习第一天 准备工作
- 黑马程序员——Java基础---访问修饰符
- 黑马程序员——Java基础---有关static(静态)的知识
- 黑马程序员——Java基础---递归
- 黑马程序员——Java基础---单例
- 黑马程序员——Java基础---面向对象之抽象
- Studio
- 1083. List Grades (25)
- Linux 命令神器 man与info
- setTimeout()和setInterval()看js的异步执行方法
- Intent在Activity之间传递值
- 《大象-Think In UML》读书笔记3
- rabbitmq-BasicQos
- sql优化(查询大数据量时sql执行时间过长)