• Loj#6433「PKUSC2018」最大前缀和(状态压缩DP)


    题面

    Loj

    题解

    先转化题意,其实这题在乘了$n!$以后就变成了全排列中的最大前缀和的和(有点拗口)。$nleq20$,考虑状压$DP$

    考虑一个最大前缀和$sumlimits_{i=1}^pa_i$,这个位置$p$是最大前缀和的右界当且仅当对于$forall r>p$有:$sumlimits_{i=p+1}^ra_ileq0$

    设$sum_i$表示二进制状态$i$的代数和,方便转移

    设$g_i$表示选了子集$i$后有多少种排列使得所有的前缀和都$<0$,于是有(从下转移而来):
    $$
    g[i] += g[i oplus (1 << j)] (sum[i]leq0,sum[ioplus(1<<j)]leq0)
    $$
    设$f_i$表示选了子集$i$后有多少种排列使得最大前缀和$=sum_i$,于是有(向上转移):
    $$
    f[i | (1 << j)]+=f[i] (sum[i]>0)
    $$
    则最后答案就是($moplus i$表示$i$的补集):
    $$
    ans=sum_{iin S}sum_i imes f_i imes g_{moplus i}
    $$

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using std::min; using std::max;
    using std::swap; using std::sort;
    typedef long long ll;
    
    template<typename T>
    void read(T &x) {
        int flag = 1; x = 0; char ch = getchar();
        while(ch < '0' || ch > '9') { if(ch == '-') flag = -flag; ch = getchar(); }
        while(ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); x *= flag;
    }
    
    const int N = 22, P = 998244353;
    int n, m, a[1 << N], f[1 << N], g[1 << N], sum[1 << N], ret;
    int lb(int x) { return x & -x; }
    
    int main () {
    	read(n), m = (1 << n) - 1;
    	for(int i = 0; i < n; ++i) read(a[1 << i]);
    	for(int i = 0; i <= m; ++i)
    		sum[i] = sum[i ^ lb(i)] + a[lb(i)];
    	g[0] = 1;
    	for(int i = 0; i < n; ++i) f[1 << i] = 1;
    	for(int i = 0; i <= m; ++i) {
    		if(sum[i] <= 0) {
    			for(int j = 0; j < n; ++j)
    				if((1 << j) & i && sum[i ^ (1 << j)] <= 0)
    					(g[i] += g[i ^ (1 << j)]) %= P;
    		} 
    	}
    	for(int i = 0; i <= m; ++i) {
    		if(sum[i] > 0) {
    			for(int j = 0; j < n; ++j)
    				if(!((1 << j) & i)) (f[i | (1 << j)] += f[i]) %= P;
    		}
    		(ret += 1ll * (sum[i] + P) % P * f[i] % P * g[m ^ i] % P) %= P;
    	}
    	printf("%d
    ", ret);
    	return 0;
    } 
    
  • 相关阅读:
    Angular中文api
    Angular各版本和组件下载
    判断一个浏览器是否支持opacity
    查找函数参数名称
    运行时代码求值
    简单的动画引擎
    利用闭包特性改写addEventListener的回调函数
    springboot指定redis库编号配置实现
    springboot获取IOC(ApplicationContext)实例
    ajax-springMVC提交表单的方式
  • 原文地址:https://www.cnblogs.com/water-mi/p/10288035.html
Copyright © 2020-2023  润新知