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 }
View Code

 

以上是关于ZOJ3329One Person Game的主要内容,如果未能解决你的问题,请参考以下文章

ZOJ3329One Person Game

ZOJ 3329:One Person Game 概率DP求期望(有环)

[ZOJ3329] One Person Game

ZOJ 3329 One Person Game

ZOJ3329One Person Game(循环型 数学期望)

ZOJ 3329 One Person Game——期望DP