【题解】P4707 重返现世

【题解】P4707 重返现世

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))=TS(1)TkCT1k1E(min(S))
我们可以把物品出现的时间记为它的值

则答案为期望下全部物品第k大值

对于子集T,第一个出现的时间即为最小值

每次出现其中任意一个的概率是 ∑ i ∈ T p i m \frac{\sum_{i\in T}p_i}{m} miTpi

最小值期望为 m ∑ i ∈ T p i \frac{m}{\sum_{i\in T}p_i} iTpim

答案为
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=TS(1)TkCT1k1pT1
但是枚举每个子集复杂度达到了指数级别

我们考虑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} TS(1)TkCT1k1

DP三要素:状态、转移、边界

转移分两种情况: 1.选了当前点 2.没选当前点

没选当前点则不产生贡献

枚举当前点的p,考虑从 d p [ i − p ] [ ] dp[i-p][] dp[ip][]转移过来

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]=TS(1)T+1jCT+11
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[ip][j]=TS(1)TjCT11

我们借助
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} CT+111=CT11+CT1j2

∑ 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} TS(1)T+1jCT+11=(1)TS(1)TjCT1+TS(1)T(j1)CT1j2

即就是
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[ip][j]+dp[ip][j1]
时间复杂度 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)jC1j1=(1)j(1)j1Cj1j1=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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值