495. Kids and Prizes
Time limit per test: 0.25 second(s)
Memory limit: 262144 kilobytes
Memory limit: 262144 kilobytes
input: standard
output: standard
output: standard
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.
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 |
题目大意:有m个人和n个装有奖品的盒子,每个人随机取走一个盒子,若存在奖品则取走,然后放回,否则直接放回,求拿走奖品的个数的期望?
方法一:概率DP (O(m))
最终期望是每个人拿到奖品的概率之和,考虑同时只存在一个人拿到盒子
第i个人拿到奖品的概率与前一个人拿到奖品的概率有关,所以设dp[i]表示第i个拿盒子的人拿到奖品的概率
则dp[i]可由两个状态转移而来:
①第i-1个拿盒子的人拿到奖品,概率为dp[i-1],则第i个拿盒子的人拿到奖品的概率为:dp[i-1]-1/n
②第i-1个拿盒子的人没有拿到奖品,概率为1-dp[i-1],则第i个拿盒子的人拿到奖品的概率为:dp[i-1]
可得状态转移方程为:dp[i]=(1-dp[i-1])*dp[i-1]+dp[i-1]*(dp[i-1]-1/n);
#include <cstdio>
using namespace std;
int n,m;
double dp[100005],nn,ans;
int main() {
while(2==scanf("%d%d",&n,&m)) {
dp[1]=ans=1;
nn=1.0/n;
for(int i=2;i<=m;++i) {
dp[i]=(1-dp[i-1])*dp[i-1]+dp[i-1]*(dp[i-1]-nn);
ans+=dp[i];
}
printf("%.9lf\n",ans);
}
return 0;
}
方法二:二项分布 (O(1))
又看到一种O(1)的算法,但是其成立的前提是m个人没有拿取到某个奖品的是相互独立的(感觉不同时取的话,第一个人必定会取到一个奖品,则后面的人取到该奖品的概率就为0了)
对于每个奖品来说,不被拿走的概率为:(n-1)/n,则不被所有人拿走的期望为:((n-1)/n)^m
则:奖品不被拿走的期望为:n*((n-1)/n)^m,所以奖品被拿走的期望为:n-n*((n-1)/n)^m
#include <cstdio>
#include <cmath>
using namespace std;
int n,m;
int main() {
while(2==scanf("%d%d",&n,&m)) {
printf("%.9lf\n",n-n*pow(1.0-1.0/n,m));
}
return 0;
}