概率计算

问题描述:
生成n个∈[a,b]的随机整数,输出它们的和为x的概率。
输入格式
  一行输入四个整数依次为n,a,b,x,用空格分隔。
输出格式
  输出一行包含一个小数位和为x的概率,小数点后保留四位小数
样例输入
2 1 3 4
样例输出
0.3333
数据规模和约定
  对于50%的数据,n≤5.
  对于100%的数据,n≤100,b≤100.

分析:
一看到题目,由于是蓝桥杯的而不是ACM的,数据都不是很大。所以我的第一感觉就是暴力遍历n次。但是由于n是一个不定的数,所以就只能再想一想了。
用动态规划法,将n次产生值看成n种状态,d[i][j]表示第i次产生值后的和为j的概率,又因为第i次的和j>=i*a && j<=i*b,又d[i][j]的产生根据d[i-1][]的情况有多种情况,例如:如果d[i-1][j-a],那么d[i][j]=d[i-1][j-a]*p(即前i-1次的和为j-a,第i次取的是a),只需要将所有可能加起来就好。
代码:

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;


double p[110][10010];

void dp(int n,int a,int b,int x);

int main()
{
    int n,x,a,b;
    cin>>n>>a>>b>>x;
    memset(p,0,sizeof(p));
    dp(n,a,b,x);
    printf("%0.4lf",p[n][x]);
    return 0;
}

void dp(int n,int a,int b,int x)
{
    double pl=1.0/(b-a+1);
    double pp=0.0;
    int i,j,k;
    for(i=1;i<=n;i++)
    {
        for(j=a*i;j<=b*i;j++)
        {
            if(i==1)
            {
                p[i][j]=pl;
            }
            else
            {
                pp=0.0;
                for(k=a;k<=b;k++)
                {
                    if(j>=k)
                    {
                        pp+=p[i-1][j-k]*pl;
                    }
                }
                p[i][j]=pp;
            }
        }
    }

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值