码迷,mamicode.com
首页 > 其他好文 > 详细

ZOJ 3329 期望DP

时间:2014-09-27 00:41:18      阅读:231      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   io   for   sp   div   c   log   

题目大意:

给定3个已经规定好k1,k2,k3面的3个色子,如果扔到a,b,c则重新开始从1 计数,否则不断叠加所有面的数字之和,直到超过n,输出丢的次数的数学期望

 

我们在此令dp[]数组记录从当前数值到结束的数学期望

假如有3个面数都为2的色子

那么dp[i] = 1.0 / 2/2/2 * dp[0] + 1.0/8*dp[i+3] +3.0/8*dp[i+4]+3.0/8*dp[i+5]+1.0/8*dp[i+6] + 1

当然那些下标大于i的dp值均为0

可是我们这样从后往前推会导致无法计算dp[0]的数值,没法推

 

从新寻找规律,可以看做

dp[i] = a[i] * dp[0] + b[i]; 1式

dp[i] = p0 * dp[0] + ∑(dp[i+k]*p[k]) + 1; 2式

1式代人2式

dp[i] = p0*dp[0] + ∑((a[i+k]*dp[0]+b[i+k]))*p[k])+1

dp[i] =( p0+∑(a[i+k]*p[k])) dp[0] + ∑(b[i+k]*p[k]) +1

 

所以a[i] =p0+∑(a[i+k]*p[k])      b[i] = ∑(b[i+k]*p[k]) +1

这样我们由后往前推不断得到所有的a[i]和b[i]值

 

dp[0] = a[0]*dp[0]+b[0]

这样我们得到a[0],b[0]就很容易得到dp[0]的值了

 

这是这段叠加处求a,b数组的代码

memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        for(int i=n;i>=0;i--){
            for(int j=3;j<=maxn;j++)
            {
                a[i]+=a[i+j] * pro[j];
                b[i]+=b[i+j] * pro[j];
            }
            a[i]+=1.0/k1/k2/k3;
            b[i]+=1;
        }

 

 1 #include <cstdio>
 2 #include <cstring>
 3 
 4 using namespace std;
 5 double pro[20],a[600],b[600];
 6 
 7 int main()
 8 {
 9     int n,k1,k2,k3,d,e,f,T;
10     scanf("%d",&T);
11     while(T--){
12         scanf("%d%d%d%d%d%d%d",&n,&k1,&k2,&k3,&d,&e,&f);
13 
14         int maxn = k1+k2+k3;
15         memset(pro,0,sizeof(pro));
16         for(int i=1;i<=k1;i++){
17             for(int j=1;j<=k2;j++){
18                 for(int k=1;k<=k3;k++)
19                     if(i!=d||j!=e||k!=f)
20                         pro[i+j+k]++;
21             }
22         }
23 
24         for(int i=3;i<=maxn;i++)
25             pro[i] = pro[i]*1.0/k1/k2/k3;
26 
27         memset(a,0,sizeof(a));
28         memset(b,0,sizeof(b));
29         for(int i=n;i>=0;i--){
30             for(int j=3;j<=maxn;j++)
31             {
32                 a[i]+=a[i+j] * pro[j];
33                 b[i]+=b[i+j] * pro[j];
34             }
35             a[i]+=1.0/k1/k2/k3;
36             b[i]+=1;
37         }
38 
39         double ans = b[0] / (1-a[0]);
40         printf("%.10f\n",ans);
41     }
42 }

 

ZOJ 3329 期望DP

标签:style   blog   color   io   for   sp   div   c   log   

原文地址:http://www.cnblogs.com/CSU3901130321/p/3995664.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!