印章
题目:共有n种图案的印章,每种图案的出现概率相同。若买了m张印章,求集齐n种印章的概率。
设dp[i][j]为i张印章,j种图案集齐的概率
当n<m时,概率为0。
由于每种图案的出现概率相同,所以每种图案的概率:1/n
设i为购买了i张印章,j为集齐j种
若j=1,即:购买了i张印章,集齐了一种图案,概率为(1/n)^(i-1),(因为还剩下i-1张印章的图案不确定,又因为每个图案的概率为1/n)
若j!=1时,即:购买了i张印章,集齐了j种,分为两种情况:
第一种:前i-1张已经集齐了j种图案
该情况,第i张印章只能是重复的图案,即:只能是j种图案中的一种,同时j种重复图案的概率为j*(1/n),因此该情况的概率为dp[i-1][j]*j*(1/n)
第二种:前i-1张只集齐了j-1种图案
该情况,第i张印章图案只能是n种图案中排除j-1种图案余下的图案,概率为[n-(j-1)](1/n),因此该情况的概率为dp[i-1][j-1]*[n-(j-1)](1/n
#include <iostream> #include <algorithm> #include <cstring> #include <cmath> #include <iomanip> using namespace std; const int N = 25; double dp[N][N]; int n,m; int main() { cin >> n >> m; double P = 1.0 / n; for(int i = 1;i <=m;i ++) { for(int j = 1;j <=n; j ++) { if(i < j) dp[i][j] = 0; if(j == 1) dp[i][j] = pow(P,i-1); else { dp[i][j] = dp[i-1][j] * (P * j) + dp[i-1][j-1] * ((n - j + 1) * P); } } } cout << fixed<<setprecision(4) << dp[m][n]; return 0; }
本文来自博客园,作者:坤k,转载请注明原文链接:https://www.cnblogs.com/fukunwang/p/16033824.html

浙公网安备 33010602011771号