题目大意:
给定
n
n
n个物品和每个物品出现的概率,收集到至少
k
k
k个物品的期望时间。
k
≤
10
k \leq 10
k≤10
思路:
好题!
容斥计算第k大的期望,考虑计算第i大的数的贡献:
∑
j
=
0
i
−
1
(
i
−
1
j
)
f
j
=
[
i
=
k
]
∑
j
=
0
i
(
i
j
)
f
j
=
[
i
=
k
−
1
]
f
i
=
∑
j
=
0
i
(
−
1
)
i
−
j
(
i
j
)
[
j
=
k
−
1
]
f
i
=
(
−
1
)
i
−
k
+
1
(
i
k
−
1
)
\begin{aligned} &\sum_{j=0}^{i-1}{i-1\choose j}f_{j}=[i=k]\\ &\sum_{j=0}^{i}{i\choose j}f_{j}=[i=k-1]\\ &f_i=\sum_{j=0}^{i}(-1)^{i-j}{i\choose j}[j=k-1]\\ &f_i=(-1)^{i-k+1}{i\choose k-1}\\ \end{aligned}
j=0∑i−1(ji−1)fj=[i=k]j=0∑i(ji)fj=[i=k−1]fi=j=0∑i(−1)i−j(ji)[j=k−1]fi=(−1)i−k+1(k−1i)
可得kth-max 的公式为:
k
t
h
(
S
)
=
∑
T
⊆
S
(
−
1
)
∣
T
∣
−
k
(
∣
T
∣
−
1
k
−
1
)
min
(
T
)
kth(S)=\sum_{T\subseteq S}(-1)^{|T|-k}{|T|-1\choose k-1}\min(T)
kth(S)=T⊆S∑(−1)∣T∣−k(k−1∣T∣−1)min(T)
其中
min
(
T
)
=
m
∑
i
∈
T
p
i
\min(T)=\frac{m}{\sum_{i\in T}p_i}
min(T)=∑i∈Tpim。
我们需要求出所有 ∣ T ∣ ≥ k |T|\geq k ∣T∣≥k的 T T T,无法直接全部求出,观察到 m = ∑ p i ≤ 1 0 4 m=\sum{p_i} \leq 10^{4} m=∑pi≤104,于是考虑DP。
设 f i , j f_{i,j} fi,j为选了 i i i个数,其中 ∑ p i = j \sum{p_i}=j ∑pi=j的方案数,时间复杂度 Θ ( n 2 m ) \Theta(n^2m) Θ(n2m)。
时间复杂度难以通过,考虑进一步优化:
设 d p j , k dp_{j,k} dpj,k 表示 ∑ p i = j \sum{p_i}=j ∑pi=j,且当前求的是第 k k k大的方案数系数之积的和,考虑依次将 n n n个物品加入,对于 d p j , k dp_{j,k} dpj,k,有加入第 i i i个物品和不加入第 i i i个物品两种选择,转移时主要考虑强制加入第 i i i种物品的选择。
对于强制选择第i个点的部分,集合的大小需要加
1
1
1,考虑从前
i
−
1
i-1
i−1个物品的状态转移过来,不难发现我们需要的式子是:
∑
i
(
−
1
)
i
+
1
−
k
(
i
k
−
1
)
f
i
,
j
−
p
\sum_{i}(-1)^{i+1-k}{i \choose k-1}f_{i,j-p}
i∑(−1)i+1−k(k−1i)fi,j−p
其中 i 枚举的是之前选择的集合大小。
但是上一个状态
d
p
j
−
p
,
k
−
1
dp_{j-p,k-1}
dpj−p,k−1可以给我们提供的式子是:
∑
i
(
−
1
)
i
−
k
+
1
(
i
−
1
k
−
2
)
f
i
,
j
−
p
\sum_{i}(-1)^{i-k+1}{i-1 \choose k-2}f_{i,j-p}
i∑(−1)i−k+1(k−2i−1)fi,j−p
不难发现之中我们所缺失的部分为:
∑
i
(
−
1
)
i
−
k
+
1
(
i
−
1
k
−
1
)
f
i
,
j
−
p
=
−
∑
i
(
−
1
)
i
−
k
(
i
−
1
k
−
1
)
f
i
,
j
−
p
=
−
d
p
j
−
p
,
k
\begin{aligned} &\sum_{i}(-1)^{i-k+1}{i-1\choose k-1}f_{i,j-p}\\ =&-\sum_{i}(-1)^{i-k}{i-1\choose k-1}f_{i,j-p}\\ =&-dp_{j-p,k} \end{aligned}
==i∑(−1)i−k+1(k−1i−1)fi,j−p−i∑(−1)i−k(k−1i−1)fi,j−p−dpj−p,k
于是到了最后我们得到了转移方程:
d
p
j
,
k
=
d
p
j
,
k
′
+
d
p
j
−
p
,
k
−
1
′
−
d
p
j
−
p
,
k
′
dp_{j,k}=dp'_{j,k}+dp'_{j-p,k-1}-dp'_{j-p,k}\\
dpj,k=dpj,k′+dpj−p,k−1′−dpj−p,k′
/*=======================================
* Author : ylsoi
* Time : 2019.1.16
* Problem : luogu4707
* E-mail : ylsoi@foxmail.com
* ====================================*/
#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a,i##_end_=b;i<=i##_end_;++i)
#define DREP(i,a,b) for(int i=a,i##_end_=b;i>=i##_end_;--i)
#define debug(x) cout<<#x<<"="<<x<<" "
#define fi first
#define se second
#define mk make_pair
#define pb push_back
typedef long long ll;
using namespace std;
void File(){
freopen("luogu4707.in","r",stdin);
freopen("luogu4707.out","w",stdout);
}
template<typename T>void read(T &_){
_=0; T f=1; char c=getchar();
for(;!isdigit(c);c=getchar())if(c=='-')f=-1;
for(;isdigit(c);c=getchar())_=(_<<1)+(_<<3)+(c^'0');
_*=f;
}
const int maxn=1000+10;
const int maxm=10000+10;
const int mod=998244353;
int n,k,m,p[maxn];
ll fac[maxn],ifac[maxn];
ll dp[maxm][maxn],ans;
ll qpow(ll x,ll y){
ll ret=1; x%=mod;
while(y){
if(y&1)ret=ret*x%mod;
x=x*x%mod;
y>>=1;
}
return ret;
}
void math_init(){
fac[0]=1;
REP(i,1,1e3)fac[i]=fac[i-1]*i%mod;
ifac[1000]=qpow(fac[1000],mod-2);
DREP(i,1e3-1,0)ifac[i]=ifac[i+1]*(i+1)%mod;
}
ll C(int x,int y){
if(x<0 || y<0 || x<y)return 0;
return fac[x]*ifac[y]%mod*ifac[x-y]%mod;
}
void init(){
read(n),read(k),read(m);
REP(i,1,n)read(p[i]);
}
void ad(ll &_,ll __){_=(_+__)%mod;}
void work(){
k=n-k+1;
dp[0][0]=1;
REP(i,1,n){
DREP(j,m,p[i]){
DREP(l,k,1){
ad(dp[j][l],dp[j-p[i]][l-1]-dp[j-p[i]][l]);
}
}
}
REP(i,1,m)ad(ans,m*qpow(i,mod-2)%mod*dp[i][k]%mod);
printf("%lld\n",(ans+mod)%mod);
}
int main(){
//File();
math_init();
init();
work();
return 0;
}