【题解】P4707 重返现世
期望下Min-Max容斥DP
E
(
k
t
h
m
a
x
(
T
)
)
=
∑
T
⊂
S
(
−
1
)
∣
T
∣
−
k
C
∣
T
∣
−
1
k
−
1
E
(
min
(
S
)
)
E(kthmax(T)) = \sum_{T\sub S} (-1)^{|T| - k} C_{|T| - 1}^{k - 1}E(\min(S))
E(kthmax(T))=T⊂S∑(−1)∣T∣−kC∣T∣−1k−1E(min(S))
我们可以把物品出现的时间记为它的值
则答案为期望下全部物品第k大值
对于子集T,第一个出现的时间即为最小值
每次出现其中任意一个的概率是 ∑ i ∈ T p i m \frac{\sum_{i\in T}p_i}{m} m∑i∈Tpi
最小值期望为 m ∑ i ∈ T p i \frac{m}{\sum_{i\in T}p_i} ∑i∈Tpim
答案为
a
n
s
=
∑
T
⊂
S
(
−
1
)
∣
T
∣
−
k
C
∣
T
∣
−
1
k
−
1
1
p
T
ans = \sum_{T\sub S} (-1)^{|T| - k} C_{|T| - 1}^{k - 1} \frac{1}{p_{T}}
ans=T⊂S∑(−1)∣T∣−kC∣T∣−1k−1pT1
但是枚举每个子集复杂度达到了指数级别
我们考虑DP
设 d p [ i ] [ j ] dp[i][j] dp[i][j] 为在前i个物品中出现k为j的 ∑ T ⊂ S ( − 1 ) ∣ T ∣ − k C ∣ T ∣ − 1 k − 1 \sum_{T\sub S} (-1)^{|T| - k} C_{|T| - 1}^{k - 1} ∑T⊂S(−1)∣T∣−kC∣T∣−1k−1
DP三要素:状态、转移、边界
转移分两种情况: 1.选了当前点 2.没选当前点
没选当前点则不产生贡献
枚举当前点的p,考虑从 d p [ i − p ] [ ] dp[i-p][] dp[i−p][]转移过来
d
p
[
i
]
[
j
]
=
∑
T
⊂
S
(
−
1
)
∣
T
∣
+
1
−
j
C
∣
T
∣
+
1
−
1
j
−
1
dp[i][j] = \sum_{T \sub S} (-1)^{|T| + 1 - j}C_{|T| + 1 -1}^{j - 1}
dp[i][j]=T⊂S∑(−1)∣T∣+1−jC∣T∣+1−1j−1
d
p
[
i
−
p
]
[
j
]
=
∑
T
⊂
S
(
−
1
)
∣
T
∣
−
j
C
∣
T
∣
−
1
j
−
1
dp[i -p][j] = \sum_{T \sub S} (-1)^{|T| - j}C_{|T| - 1}^{j - 1}
dp[i−p][j]=T⊂S∑(−1)∣T∣−jC∣T∣−1j−1
我们借助
C
∣
T
∣
+
1
−
1
j
−
1
=
C
∣
T
∣
−
1
j
−
1
+
C
∣
T
∣
−
1
j
−
2
C_{|T| +1 - 1}^{j - 1} = C_{|T| -1}^{j - 1} + C_{|T| - 1}^{j - 2}
C∣T∣+1−1j−1=C∣T∣−1j−1+C∣T∣−1j−2
有
∑
T
⊂
S
(
−
1
)
∣
T
∣
+
1
−
j
C
∣
T
∣
+
1
−
1
j
−
1
=
(
−
1
)
∑
T
⊂
S
(
−
1
)
∣
T
∣
−
j
C
∣
T
∣
−
1
j
−
1
+
∑
T
⊂
S
(
−
1
)
∣
T
∣
−
(
j
−
1
)
C
∣
T
∣
-
1
j
−
2
\sum_{T \sub S} (-1)^{|T| + 1 - j}C_{|T| + 1 -1}^{j - 1} = (-1) \sum_{T \sub S} (-1)^{|T| - j}C_{|T| -1}^{j - 1} + \sum_{T \sub S} (-1)^{|T| - (j - 1)}C_{|T| -1}^{j- 2}
T⊂S∑(−1)∣T∣+1−jC∣T∣+1−1j−1=(−1)T⊂S∑(−1)∣T∣−jC∣T∣−1j−1+T⊂S∑(−1)∣T∣−(j−1)C∣T∣-1j−2
即就是
d
p
[
i
]
[
j
]
=
-
d
p
[
i
−
p
]
[
j
]
+
d
p
[
i
−
p
]
[
j
−
1
]
dp[i][j] = -dp[i - p][j] + dp[i-p][j - 1]
dp[i][j]=-dp[i−p][j]+dp[i−p][j−1]
时间复杂度
O
(
n
m
f
)
O(nmf)
O(nmf)
设初始状态时 d p [ 0 ] [ j ] = ( − 1 ) − j C − 1 j − 1 = ( − 1 ) − j ( − 1 ) j − 1 C j − 1 j − 1 = − 1 dp[0][j] = (-1)^{-j}C_{-1}^{j - 1}=(-1)^{-j}(-1)^{j-1}C_{j-1}^{j-1} = -1 dp[0][j]=(−1)−jC−1j−1=(−1)−j(−1)j−1Cj−1j−1=−1
#include<bits/stdc++.h>
using namespace std;
inline int Read(){
int s = 0 , w = 1;
char ch = getchar();
while(ch > '9' || ch < '0'){
if(ch == '-') w = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9'){
s = (s << 1) + (s << 3) + ch - '0';
ch = getchar();
}
return s * w;
}
#define int long long
const int MAXN = 1e3 + 5 , MAXM = 1e4 + 5 , mod = 998244353;
int add(int x,int y){
x += y;
return x >= mod ? x - mod : x;
}
inline int sub(int x,int y){
x -= y;
return x < 0 ? x + mod : x;
}
int n,m,s,w,ans;
int inv[MAXM],f[12][MAXM];
#undef int
int main(){
#define int long long
n = Read() , s = n + 1 - Read() ;
m = Read();
for(int i = (inv[1] = 1) + 1 ; i <= m ; i ++){
inv[i] = inv[mod % i] * (mod - mod / i) % mod;
}
for(int i = 1 ; i <= s ; i ++) f[i][0] = -1;
for(int i = 1 ; i <= n ; i ++){
w = Read();
for(int j = m ; j >= w ; j --){
for(int k = s ; k ; k--){
f[k][j] = add(f[k][j],sub(f[k - 1][j - w] , f[k][j - w]));
}
}
}
for(int i = 1 ; i <= m ; i++){
ans = (ans + f[s][i] * inv[i] % mod) % mod;
}
cout << ans * m % mod;
return 0;
}