ABC243F Lottery[组合数学]
Posted solemntee
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ABC243F Lottery[组合数学]相关的知识,希望对你有一定的参考价值。
题意:给你
N
N
N种物品,每种被选取的概率是
P
[
i
]
P[i]
P[i],独立的取
K
K
K次,问取到的物品种类数恰好是
M
M
M的概率
思路:
如果考虑物品选取的先后次序,对于选取物品的序列
a
1
a
2
a
3
.
.
.
a
K
a_1a_2a_3...a_K
a1a2a3...aK(其中
a
i
a_i
ai表示第
i
i
i次选取的物品
i
d
id
id)
P
(
a
1
a
2
.
.
.
a
K
)
=
∏
i
=
1
K
P
[
a
i
]
P(a_1a_2...a_K)=\\prod_i=1^K P[a_i]
P(a1a2...aK)=i=1∏KP[ai]
现在需要求物品种类数为
M
M
M的概率,不妨设第
i
i
i种物品
i
d
id
id为
b
i
b_i
bi个数为
c
i
c_i
ci个,则总概率为
P
=
K
!
∏
i
=
1
M
P
[
b
i
]
c
i
c
i
!
P=K!\\prod_i=1^M \\frac P[b_i]^c_ic_i!
P=K!i=1∏Mci!P[bi]ci
显然这个式子可以通过
d
p
dp
dp递推求出
设
d
p
[
i
]
[
j
]
[
k
]
dp[i][j][k]
dp[i][j][k]为前
i
i
i个取了
j
j
j种共取
k
k
k个的概率和
枚举第
i
i
i种物品选取的数量容易知道递推关系,不赘述
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mod=998244353;
ll poww(ll a,ll b)
ll t=1;
while(b)
if(b&1)t=a*t%mod;
a=a*a%mod;
b>>=1;
return t;
ll inv(ll x)
return poww(x,mod-2);
ll P1[10000005],P2[10000005];
void init()
P1[0]=1;
for(int i=1;i<=10000000;i++)P1[i]=1LL*P1[i-1]*i%mod;
P2[10000000]=inv(P1[10000000]);
for(int i=9999999;i>=0;i--)P2[i]=1LL*P2[i+1]*(i+1)%mod;
ll dp[55][55][55];
int main()
int K,M,N;
scanf("%d%d%d",&N,&M,&K);
ll sum=0;
vector<ll>W(N+1),P(N+1);
init();
for(int i=1;i<=N;i++)
scanf("%lld",&W[i]);
sum+=W[i];
for(int i=1;i<=N;i++)P[i]=1LL*W[i]*inv(sum)%mod;
dp[0][0][0]=1;
for(int i=1;i<=N;i++)
for(int j=0;j<=M;j++)
for(int k=0;k<=K;k++)
for(int l=0;l<=k;l++)
if(j-(l>0)>=0)dp[i][j][k]=(dp[i][j][k]+dp[i-1][j-(l>0)][k-l]*poww(P[i],l)%mod*inv(P1[l]%mod)%mod)%mod;
printf("%lld",dp[N][M][K]*P1[K]%mod);
return 0;
以上是关于ABC243F Lottery[组合数学]的主要内容,如果未能解决你的问题,请参考以下文章