• ZOJ 3329 One Person Game (经典概率dp+有环方程求解)


    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3329

    题意:
    现在有三个骰子,分别有k1,k2和k3面,面上的点就是1~ki。每次扔骰子,如果这三个骰子的值分别对应为a,b,c,那么将值初始化为0,否则就将三个骰子的点值和相加。求大于等于n的扔骰子次数期望。

    思路:

    这道题目主要在于推公式,看着别人的题解想了好久。

    先设$E(i)$为此时和为i时还需要的期望,易得(1):$E(i)=sum (E(i+k)P(k))+E(0)P(0)+1$(这里$P(k)$为点值和为k的概率,$P(0)$就是对应a,b,c的概率)。

    现在我们要求解的是$E(0)$,而且发现每个式子中都会包含$E(0)$。

    当遇到这样的情况时我们可以先假设一下,假设(2):$E(i)=A(i)E(0)+B(i)$,那么(3):$E(i+k)=A(i+k)E(0)+B(i+k)$。

    将(3)式带入(1)式,得(4):$E(i)=(sum (A(i+k)P(k))+P(0))*E(0)+sum (B(i+k)P(k))+1$。

    将(2)式和(4)式作比较,可得:

    (5):$A(i)=sum (A(i+k)P(k))+P(0)$

    (6):$B(i)=sum (B(i+k)P(k))+1$

    而由(2)式我们又可以推出$E(0)=frac{B(0)}{1-A(0)}$。

    所以现在要的就是A(0)和B(0)的值,这个很简单,由(5)、(6)递推得到即可。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<vector>
     6 #include<stack>
     7 #include<queue>
     8 #include<cmath>
     9 #include<map>
    10 #include<set>
    11 using namespace std;
    12 typedef long long ll;
    13 const int INF = 0x3f3f3f3f;
    14 const int maxn=500+5;
    15 
    16 int n,k1,k2,k3,a,b,c;
    17 double p0;
    18 double A[maxn],B[maxn],p[maxn];
    19 
    20 int main()
    21 {
    22     //freopen("in.txt","r",stdin);
    23     int T;
    24     scanf("%d",&T);
    25     while(T--)
    26     {
    27         cin>>n>>k1>>k2>>k3>>a>>b>>c;
    28         memset(p,0,sizeof(p));
    29         p0=1.0/k1/k2/k3;
    30         for(int i=1;i<=k1;i++)
    31         for(int j=1;j<=k2;j++)
    32         for(int t=1;t<=k3;t++)
    33         {
    34             if(i==a && j==b && t==c)  continue;
    35             p[i+j+t]+=p0;
    36         }
    37         for(int i=n;i>=0;i--)
    38         {
    39             A[i]=p0,B[i]=1;
    40             for(int t=3;t<=k1+k2+k3;t++)
    41             {
    42                 if(i+t>n)  continue;
    43                 A[i]+=A[i+t]*p[t];
    44                 B[i]+=B[i+t]*p[t];
    45             }
    46         }
    47         printf("%.16f
    ",B[0]/(1-A[0]));
    48     }
    49     return 0;
    50 }
  • 相关阅读:
    phpspider爬虫框架的使用
    【php设计模式】责任链模式
    【php设计模式】策略模式
    【php设计模式】观察者模式
    【php设计模式】模板模式
    【温故知新】php 魔术方法
    【php设计模式】享元模式
    Java50道经典习题-程序18 乒乓球赛
    Java50道经典习题-程序19 输入行数打印菱形图案
    Java50道经典习题-程序20 求前20项之和
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7449467.html
Copyright © 2020-2023  润新知