印章

题目:共有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;    
}

 

posted @ 2022-03-21 11:09  坤k  阅读(262)  评论(0)    收藏  举报