• [PKUSC2018]最大前缀和(状压DP)


    题目大意:求给定的 $n$ 个数的所有排列的最大前缀和(不能为空)之和对 $10^9+7$ 取模的值。

    $1le nle 20,1lesum|a_i|le 10^9$。


    神级DP。杂题选讲的神级毒瘤讲题人CDW讲的。

    考虑一个集合 $S$ 能作为最大前缀和出现的方案数。(即贡献系数)

    发现前 $|S|$ 个数满足最大前缀和是整个序列,后 $n-|S|$ 个数满足最大前缀和 $<0$。(虽然 $le 0$ 也行,但为了避免重复统计就要 $<0$)

    设 $f[S]$ 为在 $S$ 的所有排列中,最大前缀和 $<0$ 的个数。

    设 $g[S]$ 为在 $S$ 的所有排列中,最大前缀和 $=sum[S]$ 的个数。($sum$ 是和)

    $f[S]=egin{cases}0&sum[S]ge 0\ sumlimits_{iin S}f[S-{i}]&sum[S]<0end{cases}$

    初始 $f[0]=1$。

    解释一下,如果 $sum[S]ge 0$,那么最大前缀和不会小于 $0$。否则枚举最后一个数,当且仅当前面的最大前缀和 $<0$ (或者前面没有数,所以 $f[0]=1$)且 $sum[S]<0$ 时才可以。第二个条件已经保证满足了。

    $g[S] ightarrow g[S+(1<<i)](sum[S]ge 0,i otin S)$

    初始 $g[{i}]=1$。

    解释一下,考虑从已有状态扩展,枚举在 $S$ 前加一个数 $i$,当且仅当 $S$ 最大前缀和是自己时,新序列最大前缀和才是自己。、

    答案为 $sum sum[S]g[S]f[U-S]$。

    时间复杂度 $O(n2^n)$。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int mod=998244353;
    #define FOR(i,a,b) for(int i=(a);i<=(b);i++)
    #define ROF(i,a,b) for(int i=(a);i>=(b);i--)
    #define MEM(x,v) memset(x,v,sizeof(x))
    inline int read(){
        char ch=getchar();int x=0,f=0;
        while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
        while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
        return f?-x:x;
    }
    int n,a[22],ans,f[1111111],g[1111111];
    ll S[1111111];
    int main(){
        n=read();
        FOR(i,0,n-1) a[i]=read(),g[1<<i]=1;
        FOR(i,0,(1<<n)-1) FOR(j,0,n-1) if((i>>j)&1) S[i]+=a[j];
        f[0]=1;
        FOR(i,0,(1<<n)-1){
            if(S[i]>=0){FOR(j,0,n-1) if(!((i>>j)&1)) g[i|(1<<j)]=(g[i|(1<<j)]+g[i])%mod;}
            else FOR(j,0,n-1) if((i>>j)&1) f[i]=(f[i]+f[i^(1<<j)])%mod;
        }
        FOR(i,0,(1<<n)-1) ans=(ans+1ll*(S[i]+mod)%mod*g[i]%mod*f[((1<<n)-1)^i])%mod;
        printf("%d
    ",ans);
    }
    View Code
  • 相关阅读:
    实验一 命令解释程序的编写
    试验二
    实验一 命令解释程序的编写(重交)
    Sqlserver数据库帮助类(EFTools)
    js验证
    sqlserver中从日期字段取得月份
    IIS不可用或者有问题解决方法
    professional email address collections
    从psd文件到html
    空白符对HTML结构的影响与解决方案
  • 原文地址:https://www.cnblogs.com/1000Suns/p/10922069.html
Copyright © 2020-2023  润新知