ZOJ 3329 One Person Game 概率dp、求期望

来源:互联网 发布:药品集中采购系统sql 编辑:程序博客网 时间:2024/05/21 10:45

概率求期望入门推荐文章:

http://kicd.blog.163.com/blog/static/126961911200910168335852/

题意:(有环、倒推)

投掷3枚骰子,如果dice1 = a,dice2 = b,dice3 = c。那么你的点数置为0,否则加上这三枚点数之和。

问你点数最终超过n,所需要投掷次数的期望。


思路:

正如我们所见,这个期望是有环的,就是可以可以回到0,因此我们需要进行式子替换。

dp[i]:从i出发,到游戏结束所需要投掷骰子次数的期望。

引用一下别人的blog:(http://blog.csdn.net/xingyeyongheng/article/details/25639827)

(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])可求出 

code:

#include <cstring>#include <cstdlib>#include <cstdio>#include <iomanip>#include <algorithm>#include <iostream>using namespace std;typedef long long LL;const int MAXN = 550;double a[MAXN], b[MAXN], dp[MAXN];double p[30];int main(){    ios::sync_with_stdio(false);    int T;    int n, k1, k2, k3, A, B, C;    while(cin>>T)    {        while(T--)        {            cin>>n>>k1>>k2>>k3>>A>>B>>C;            double t = 1.0/(k1*k2*k3);            //get the Matrix p;            memset(p, 0, sizeof(p));            p[0] = t;            for(int i = 1;i <= k1; i++)                for(int j = 1;j <= k2; j++)                    for(int z = 1;z <= k3; z++)                            p[i+j+z] += t;            //get the Matrix a, b;            p[A+B+C] -= p[0];            int tot = k1+k2+k3;            memset(a, 0, sizeof(a));            memset(b, 0, sizeof(b));            for(int tn = n; tn >= 0; tn--)            {                a[tn] = p[0];                b[tn] = 1;                for(int i = 3;i <= tot; i++)                {                    if(p[i] != 0)                    {                        a[tn] += a[tn+i] * p[i];                        b[tn] += b[tn+i] * p[i];                    }                }            }                        //get the dp[0];            //cout<<"a[0] = "<<a[0]<<endl;            //cout<<"b[0] = "<<b[0]<<endl;            double res = b[0]/(1-a[0]);            cout<<fixed<<setprecision(8)<<res<<endl;        }    }    return 0;}            


0 0
原创粉丝点击