问题描述
共有n种图案的印章,每种图案的出现概率相同。小A买了m张印章,求小A集齐n种印章的概率。
输入格式
一行两个正整数n和m
输出格式
一个实数P表示答案,保留4位小数。
样例输入
2 3
样例输出
0.7500
数据规模和约定
1≤n,m≤20
解题思路:
状态表示:用f[i][j]表示i个印章集齐j种图案的概率。
状态计算(这里要分三种情况):
1.当i<j时,这时总量不够,无法集齐印章。f[i][j]=0;
2.当j=1时,即只需要集齐一种图案即可,随便哪一种都可以。i=1时,f[i][j]=1;i>1时,f[i][j]=(1/n)^(i-1)。
3.在第i次集齐j种图案时,分两种情况,一是在第i-1次已经集齐j种图案,二是在第i次集齐j种图案;
即有状态方程:f[i][j] = f[i - 1][j] * p * j + f[i - 1][j - 1] * p * (n - j + 1);
具体代码如下:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
const int N = 25;
double f[N][N];//注意题目的精度要求
int main()
{
int n, m;
cin >> n >> m;
double p = 1.00 / n;
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
{
if (i < j) f[i][j] = 0;
if (j == 1)f[i][j] = pow(p, i - 1);
else f[i][j] = f[i - 1][j] * p * j + f[i - 1][j - 1] * p * (n - j + 1);
}
}
printf("%.4lf", f[m][n]);
return 0;
}