zoj 3229 期望dp 比较经典

该博客介绍了如何运用期望动态规划(dp)解决ZOJ 3229题目,涉及三个骰子游戏,目标是求掷骰子次数的期望值。博主分享了思路和代码实现,通过记忆化搜索计算每个状态的期望值,并最终得出答案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*
思路从这个
博客:http://blog.youkuaiyun.com/morgan_xww/article/details/6775853
思路:(//后面是我自己添加上的帮助理解,其余解题思路的是转载,我用的记忆化搜索写的)
 dp求期望的题。 
    题意: 
    有三个均匀的骰子,分别有k1,k2,k3个面,初始分数是0, 
    当掷三个骰子的点数分别为a,b,c的时候,分数清零,否则分数加上三个骰子的点数和, 
    当分数>n的时候结束。求需要掷骰子的次数的期望。 
    题解: 
    设 E[i]表示现在分数为i,到结束游戏所要掷骰子的次数的期望值。 
    显然 E[>n] = 0; E[0]即为所求答案; 
    E[i] = ∑Pk*E[i+k] + P0*E[0] + 1; (Pk表示点数和为k的概率,P0表示分数清零的概率)//因为E[i+k]里面含有E[0]项所以说E[0]的系数并不是P0而是一个变元
    由上式发现每个 E[i]都包含 E[0],而 E[0]又是我们要求的,是个定值。 
    设 E[i] = a[i]*E[0] + b[i]; //=>E[0]=a[0]*E[0]+b[0] =>E[0]=b[0]/(1-a[0]);
    将其带入上面的式子: 
    E[i] = ( ∑Pk*a[i+k] + P0 )*E[0] + ∑Pk*b[i+k] + 1; 
    显然, 
    a[i] = ∑Pk*a[i+k] + P0; 
    b[i] = ∑Pk*b[i+k] + 1; 
    当 i > n 时: 
    E[i] = a[i]*E[0] + b[i] = 0; 
    所以 a[i>n] = b[i>n] = 0; 
    可依次算出 a[n],b[n]; a[n-1],b[n-1] ... a[0],b[0]; 
    则 E[0] = b[0]/(1 - a[0]); 
*/
#include<stdio.h>
#include<string.h>
#define N 550
int n,k1,k2,k3,a,b,c;
double dpa[N],dpb[N],p0;
double dfsb(int f) {
 int i,j,k;
 if(f>n)return 0;
 if(dpb[f])return dpb[f];
 for(i=1;i<=k1;i++)
    for(j=1;j<=k2;j++)
 for(k=1;k<=k3;k++) {
  if(i==a&&j==b&&c==k)continue;
    dpb[f]+=dfsb(f+i+j+k)*p0;
 }
 return dpb[f]=dpb[f]+1;
}
double dfsa(int f) {
   int i,j,k;
 if(f>n)return 0;
 if(dpa[f])return dpa[f];
 for(i=1;i<=k1;i++)
    for(j=1;j<=k2;j++)
 for(k=1;k<=k3;k++) {
  if(i==a&&j==b&&c==k)continue;
    dpa[f]+=dfsa(f+i+j+k)*p0;
 }
 return dpa[f]=dpa[f]+p0;
}
int main() {
     int t;
     scanf("%d",&t);
     while(t--) {
        scanf("%d%d%d%d%d%d%d",&n,&k1,&k2,&k3,&a,&b,&c);
         memset(dpa,0,sizeof(dpa));
         memset(dpb,0,sizeof(dpb));
         p0=1.0/(k1*k2*k3);
        printf("%.15f\n",dfsb(0)/(1-dfsa(0)));
     }
return 0;}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值