ZOJ3329One Person Game
Posted 蒟蒻LQL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ZOJ3329One Person Game相关的知识,希望对你有一定的参考价值。
题意
你有三枚色子,第i个色子有ki面,你有一个计数器。
1.开始的时候将计数器调至0
2.扔三个色子,如果色子1是a,色子2是b,色子3是c,则将计数器归零。否则计数器加上三个色子的和。
3.如果计数器的数字大于等于n游戏结束,否则重复步骤
计算扔色子次数的期望
分析
通过带入系数解决概率DP问题。
f[i]为当前计数器的数字是i,到游戏结束的期望次数是多少。
f[i]=sum(f[i+k]*p)+1+f[0]*p。
因为f[0]就是我们所求的东西,所以我们令f[i]=A[i]*f[0]+B[i]
带入整理得f[i]=(sum(A[i+k]*p)+p)*f[0]+sum(p*B[i+k])+1
观察得到 A[i]=sum(p*A[i+k])+p
B[i]=sum(p*B[i+k])+1
ans=f[0]=B[0]/(1-A[0])
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 6 using namespace std; 7 const int maxn=600; 8 double A[maxn],B[maxn]; 9 int T,n,K1,K2,K3,a,b,c; 10 11 int main(){ 12 scanf("%d",&T); 13 for(int t=1;t<=T;t++){ 14 scanf("%d%d%d%d%d%d%d",&n,&K1,&K2,&K3,&a,&b,&c); 15 memset(A,0,sizeof(A)); 16 memset(B,0,sizeof(B)); 17 for(int i=0;i<=n;i++){ 18 for(int j=1;j<=K1;j++){ 19 for(int k=1;k<=K2;k++){ 20 for(int l=1;l<=K3;l++){ 21 if(j!=a||k!=b||l!=c){ 22 int sum=j+k+l; 23 if(i-sum>=0){ 24 A[i]+=A[i-sum]*(double)1/(K1*K2*K3); 25 B[i]+=B[i-sum]*(double)1/(K1*K2*K3); 26 } 27 } 28 } 29 } 30 } 31 A[i]+=(double)1/(K1*K2*K3); 32 B[i]+=1; 33 } 34 double ans=B[n]/(1-A[n]); 35 printf("%.15f\n",ans); 36 } 37 return 0; 38 }
以上是关于ZOJ3329One Person Game的主要内容,如果未能解决你的问题,请参考以下文章
ZOJ 3329:One Person Game 概率DP求期望(有环)