luogu P4707 重返现世
https://www.luogu.com.cn/problem/P4707
\(kthmin-max\)容斥入门题
懒得证明了
式子就是
\[\max(S)=\sum_{T⊆S}(-1)^{|T|-k}\binom{|T|-1}{k-1}\min(T)
\]
设计DP
\(f[i][j][k]\)表示考虑前\(i\)个元素\(\sum p=j\) 计算中\(k\)的大小(主要是方便转移下面拆组合数)
然后分选不选转移即可
这篇写得详细一些
https://www.luogu.com.cn/blog/Sooke/solution-p4707
code:
#include<bits/stdc++.h>
#define ll long long
#define mod 998244353
using namespace std;
ll qpow(ll x, ll y) {
ll ret = 1;
for(; y; y >>= 1, x = x * x % mod) if(y & 1) ret = ret * x % mod;
return ret;
}
int n, K, m, p[1005];
ll f[2][10005][15];
int main() {
scanf("%d%d%d", &n, &K, &m), K = n - K + 1;
for(int i = 1; i <= n; i ++) scanf("%d", &p[i]);
f[0][0][0] = 1;
for(int i = 1; i <= n; i ++) {
memset(f[i & 1], 0, sizeof f[i & 1]);
f[i & 1][0][0] = 1;
for(int j = 1; j < p[i]; j ++)
for(int k = 1; k <= K; k ++) f[i & 1][j][k] = f[(i - 1) & 1][j][k];
for(int j = p[i]; j <= m; j ++)
for(int k = 1; k <= K; k ++)
f[i & 1][j][k] = (f[(i - 1) & 1][j][k] + f[(i - 1) & 1][j - p[i]][k - 1] - f[(i - 1) & 1][j - p[i]][k] + mod) % mod;
}
ll ans = 0;
for(int i = 1; i <= m; i ++) (ans += f[n & 1][i][K] * qpow(i, mod - 2) % mod * m % mod) %= mod;
printf("%lld", ans);
return 0;
}