[luogu4707]重返现世——min-max容斥拓展+动态规划

题目大意:

给定 n n n个物品和每个物品出现的概率,收集到至少 k k k个物品的期望时间。
k ≤ 10 k \leq 10 k10

思路:

好题!

容斥计算第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=0i1(ji1)fj=[i=k]j=0i(ji)fj=[i=k1]fi=j=0i(1)ij(ji)[j=k1]fi=(1)ik+1(k1i)
可得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)=TS(1)Tk(k1T1)min(T)
其中 min ⁡ ( T ) = m ∑ i ∈ T p i \min(T)=\frac{m}{\sum_{i\in T}p_i} min(T)=iTpim

我们需要求出所有 ∣ T ∣ ≥ k |T|\geq k Tk T T T,无法直接全部求出,观察到 m = ∑ p i ≤ 1 0 4 m=\sum{p_i} \leq 10^{4} m=pi104,于是考虑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 i1个物品的状态转移过来,不难发现我们需要的式子是:
∑ 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+1k(k1i)fi,jp
其中 i 枚举的是之前选择的集合大小。

但是上一个状态 d p j − p , k − 1 dp_{j-p,k-1} dpjp,k1可以给我们提供的式子是:
∑ 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)ik+1(k2i1)fi,jp
不难发现之中我们所缺失的部分为:
∑ 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)ik+1(k1i1)fi,jpi(1)ik(k1i1)fi,jpdpjp,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+dpjp,k1dpjp,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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值