SGU 495 Kids and Prizes (概率DP)

ICPC (International Cardboard Producing Company) is in the business of producing cardboard boxes. Recently the company organized a contest for kids for the best design of a cardboard box and selected M winners. There are N prizes for the winners, each one carefully packed in a cardboard box (made by the ICPC, of course). The awarding process will be as follows:
All the boxes with prizes will be stored in a separate room.
The winners will enter the room, one at a time.
Each winner selects one of the boxes.
The selected box is opened by a representative of the organizing committee.
If the box contains a prize, the winner takes it.
If the box is empty (because the same box has already been selected by one or more previous winners), the winner will instead get a certificate printed on a sheet of excellent cardboard (made by ICPC, of course).
Whether there is a prize or not, the box is re-sealed and returned to the room.
The management of the company would like to know how many prizes will be given by the above process. It is assumed that each winner picks a box at random and that all boxes are equally likely to be picked. Compute the mathematical expectation of the number of prizes given (the certificates are not counted as prizes, of course).

Input
The first and only line of the input file contains the values of N and M ( ).

Output
The first and only line of the output file should contain a single real number: the expected number of prizes given out. The answer is accepted as correct if either the absolute or the relative error is less than or equal to 10 -9.

Example(s)
sample input sample output
5 7 3.951424

sample input sample output
4 3 2.3125


题意:n个盒子里装有礼物,m个人随机选择礼物,选完之后空盒子放回,问选中的礼物数的期望
解法一:
对于每个礼物来说 不被选中的概率是((n-1)/n)m
那么被选中的概率就是1-((n-1)/n)m
被选中的期望就是n(1-((n-1)/n)m)

#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        double p=(double)(n-1)/n;
        double ans=n*(1-pow(p,m));
        printf("%.10lf\n",ans);
    }
    return 0;
}

解法二:
概率dp,m个人n个奖品,一个一个的去选奖品,奖品被选中以后把盒子放回,求最后发出奖品的期望
dp[i]代表第i个人摸到奖品的概率,如果第i-1个人没摸到,则为dp[i-1],如果摸到则为dp[i-1]-1/n。

dp[i]=dp[i-1](1-dp[i-1])+dp[i-1](dp[i-1]-1/n)=dp[i-1]*(1-1/n);

我们发现是一个等比数列,dp[1]=1,对其求和即可.

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int main(void)
{
	int m,n;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		double p=1-1.0/n;
		double ex=1;
		while(m){
			if(m&1)
                ex*=p;
			m>>=1;
			p*=p;
		}
		printf("%.10lf\n",(1-ex)*n);
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值