有(n)个不同的数,每秒有(p_i)的概率取出(i)。
问第一次出现第(k)个不同数的期望步数。
(nle 1000),(mle 10000),(n-kle 10)
(p_i)表示为(frac{a_i}{m})的形式。
介绍个新姿势:kth-minmax容斥。
[kthmax(S)=sum_{empty
eq Tsubseteq S} (-1)^{|T|-k}inom{|T|-1}{k-1}min(T)
]
具体证明和普通的minmax容斥一样,同样考虑把(S)排序后,其中某个数(S_i)会算多少次。然后可以发现恰好只算到了(S_{n-k+1})(注意是第(k)大)。
回到这题。首先(kleftarrow n-k+1),即第(k)小变成第(k)大。
套式子。后面(min)的部分可以表示为(sum_{ige 0}(1-sum_{jin T}p_j)^i(sum_{jin T}p_j)(i+1)=frac{1}{sum_{jin T}p_j})。
列出答案式子:(sum_{T}(-1)^{|T|-k}inom{|T|-1}{k-1}frac{1}{sum_{jin T}p_j}),考虑把(sum_{jin T}p_j)相同的一起算,得到朴素的DP做法,记下当前搞到哪个数,(|T|)为多少,(sum_{jin T}p_j)为多少。
实际上可以发现:((-1)^{|T|-k}inom{|T|-1}{k-1}=(x-1)^{|T|-1}[x^{k-1}])。
于是改进DP:设(f_{i,j}),考虑前(i)个数,(sum_{jin T}p_j)为(j),存下一个多项式。转移的时候乘((x-1))。
因为(kle 11),时间是(O(nm(n-k))),能过。
细节:初值(f_{0,0}=frac{1}{x-1}),不要忘了。
using namespace std;
#include <bits/stdc++.h>
#define N 1005
#define M 10005
#define K 13
#define ll long long
#define mo 998244353
ll qpow(ll x,ll y=mo-2){
ll r=1;
for (;y;y>>=1,x=x*x%mo)
if (y&1)
r=r*x%mo;
return r;
}
int n,k,m;
int p[N];
int C[N][N];
int f[M][K];
int main(){
// freopen("in.txt","r",stdin);
scanf("%d%d%d",&n,&k,&m);
k=n-k+1;
for (int i=1;i<=n;++i)
scanf("%d",&p[i]);
for (int i=0;i<=n;++i){
C[i][0]=1;
for (int j=1;j<=i;++j)
C[i][j]=(C[i-1][j-1]+C[i-1][j])%mo;
}
for (int i=0;i<k;++i)
f[0][i]=-1;
for (int i=0;i<n;++i)
for (int j=m-p[i+1];j>=0;--j){
(f[j+p[i+1]][0]-=f[j][0])%=mo;
for (int t=1;t<k;++t)
f[j+p[i+1]][t]=((ll)f[j+p[i+1]][t]-f[j][t]+f[j][t-1])%mo;
}
ll ans=0;
for (int j=1;j<=m;++j)
(ans+=qpow(j)*f[j][k-1])%=mo;
ans=(ans+mo)%mo*m%mo;
printf("%lld
",ans);
return 0;
}