一、题目:
输入案例:
2 3
输出案例:
0.7500
数据规模和约定
1≤n,m≤20
二、解题思路:
三、实现代码:
#include<bits/stdc++.h>
using namespace std;
/*
* dp[i][j] 含义: 小明买了 i 张印章, 集齐 j 种印章的概率
* dp[1][1] --> 当 i = 1, 小明集齐1种印章的概率为 1
* dp[i][1] --> 当 i >= 1, 小明集齐1种印章,也就是买的全是同一种印章的概率为 (1.0/1)^(i-1)
* dp[i][j] --> 当 i < j, 小明集齐j种印章的概率为 0
* */
double dp[22][22], p;
int main() {
int n,m;
cin>>n>>m;
for (int i = 1; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
if (i < j) {
dp[i][j] = 0;
continue;
}
if (j == 1) {
dp[i][j] = pow(1.0/n, i-1); // p^(i-1)
} else {
// 我们买的第 i 张,有两种状态,一:跟前面买的 i-1 张中有重复 二:跟前面买的 i-1 张中没有重复
// j / n 就是前 i - 1 张已经集齐 j 种印章,第 i 张重复的情况下集齐的概率 , (n-(j-1))/n 就是 i-1 张已经集齐 j - 1 张,第 i 张没重复的情况下集齐的概率
dp[i][j] = dp[i-1][j]*((double)j/n) + dp[i-1][j-1] * ((double)(n-(j-1))/n);
}
}
}
cout<<setprecision(4)<<fixed<<dp[m][n]<<endl;
return 0;
}