kthmin-max容斥板子題git
題目要求至少獲得\(k\)種東西的指望時間,轉換後是求獲得全集倒數第\(k\)個得到的東西的指望時間,而後能夠套式子了數組
而後咱們這個答案式子作dpspa
\(dp_{i,j,k}\)表明前\(i\)個東西處理後\(\sum p=j\)且爲求\(kmax\)的貢獻值code
這裏說一下第三個狀態,這個\(k\)其實就是式子裏面的\(k\),咱們設它只是爲了轉移這個組合式子而已(利用組合數的遞推式子)get
轉移有it
初始狀態io
目標class
而後滾動一下數組就行了im
Code:di
#include <cstdio> #include <cctype> template <class T> void read(T &x) { x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); } const int mod=998244353; inline int add(int a,int b){return a+b>=mod?a+b-mod:a+b;} #define mul(a,b) (1ll*(a)*(b)%mod) int qp(int d,int k){int f=1;while(k){if(k&1)f=mul(f,d);d=mul(d,d),k>>=1;}return f;} int n,m,K,dp[2][10010][11],p[10010],cur; int main() { read(n),read(K),read(m); K=n-K+1; for(int i=1;i<=n;i++) read(p[i]); dp[0][0][0]=1; for(int i=1;i<=n;i++) { cur^=1; for(int j=0;j<=m;j++) for(int k=0;k<=K;k++) { dp[cur][j][k]=dp[cur^1][j][k]; if(j>=p[i]&&k) { dp[cur][j][k]=add(dp[cur][j][k],mod-dp[cur^1][j-p[i]][k]); dp[cur][j][k]=add(dp[cur][j][k],dp[cur^1][j-p[i]][k-1]); } } } int ans=0; for(int i=1;i<=m;i++) ans=add(ans,mul(m,mul(qp(i,mod-2),dp[cur][i][K]))); printf("%d\n",ans); return 0; }
2019.3.2