【组队赛#8】BNU 1084 Expected Allowance (母函数)

来源:互联网 发布:风云无双天劫进阶数据 编辑:程序博客网 时间:2024/06/06 12:26

 【题目链接】click here~~  

题目大意】给出一个n个骰子,每个骰子有m个面,给出一个削减值k,投掷一次,所有的骰子点数和要减去k,如果减去的值小于1,则得到的钱也至少是1;要求出他能得到钱的期望值

解题思路】母函数!!,关键在于理解题意思路:(每个点数出现的概率要计算) 具体看代码吧

母函数:

#include <bits/stdc++.h>#include <iostream>#include <string.h>#include <stdio.h>#include <math.h>using namespace std;double c1[100005],c2[100005];int main(){    int i,j,k,n,m,p;    double sum;    while(cin>>n>>m>>p)    {        if(n==0&&m==0&&p==0) break;        sum=0;        for(i=1; i<=m; i++){//初始化            c1[i]=1;        //系数为1            c2[i]=0;        }        for(i=1; i<n; i++){            for(j=1; j<=m*i; j++)//第i个骰子投掷出m面的可能数                for(k=1; k<=m; k++){//总共m面                    c2[j+k]+=c1[j];                }            memcpy(c1,c2,sizeof(c2));            memset(c2,0,sizeof(c2));        }//        for(int i=1;i<=m;i++)//        {//            cout<<c1[i]<<" "<<c2[i]<<endl;//        }        for(int i=n; i<=n*m; i++){//n个骰子,每个m面,最小点数为n,最大点数为n*m            if(i>p)                sum+=c1[i]*(double)(i-p);            else                sum+=c1[i];        }//          cout<<"#"<<sum<<"#"<<endl;        printf("%.8lf\n",sum/pow(m,n));    }    return 0;}
当时比赛最后十几分钟,突然想到一个递推的思路,大致思路是这样:每次从1到m面搜一遍,找出出现1到n*m面的所有可能数,当以骰子个数为0 时结束,且每次计算ans的值

dfs:

#include <bits/stdc++.h>using namespace std;double pow(double n,double m){    double res=1;    for(int i=1; i<=n; i++)        res*=(m);    return res;}double  ans;double n,m,k;double sum;void dfs(int a,int b){    if(a==0)    {        ans+=(b-k<1?1:(b-k));        return;    }    for(int i=1;i<=m;i++)    {        dfs(a-1,b+i);    }}int main(){    while(cin>>n>>m>>k)    {        ans=0;        if(n==0&&m==0&&k==0) break;        dfs(n,0);        //printf("%lf\n",ans);        double ans2=pow(n,m);        double result=(ans/ans2);        printf("%.8lf\n",result);    }    return 0;}

1 1
原创粉丝点击