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;
}

发布了36 篇原创文章 · 获赞 10 · 访问量 1909

猜你喜欢

转载自blog.csdn.net/weixin_44003265/article/details/103864140
sgu