zoukankan      html  css  js  c++  java
  • 【LOJ6433】【PKUSC2018】最大前缀和

    【LOJ6433】【PKUSC2018】最大前缀和

    题面

    题目描述

    小 C 是一个算法竞赛爱好者,有一天小 C 遇到了一个非常难的问题:求一个序列的最大子段和。

    但是小 C 并不会做这个题,于是小 C 决定把序列随机打乱,然后取序列的最大前缀和作为答案。

    小 C 是一个非常有自知之明的人,他知道自己的算法完全不对,所以并不关心正确率,他只关心求出的解的期望值,现在请你帮他解决这个问题,由于答案可能非常复杂,所以你只需要输出答案乘上 (n!) 后对 (998244353) 取模的值,显然这是个整数。

    注:最大前缀和的定义:(forall i in [1,n])(sum_{j=1}^{i}a_j) 的最大值。

    输入格式

    第一行一个正整数 (n),表示序列长度。

    第二行 (n)个数,表示原序列 (a[1..n]),第 (i) 个数表示 (a[i])

    输出格式

    输出一个非负整数,表示答案。

    样例

    输入样例

    2
    -1 2
    

    输出样例

    3
    

    提示与说明

    对于(10\%)的数据,有(1leq nleq 9)

    对于(40\%)的数据,有(1leq nleq 15)

    另有(10\%)的数据,满足(a)中最多只有一个负数。

    另有(10\%)的数据,满足(|a[i]|leq 2)

    对于(100\%)的数据,满足(1leq nleq 20)(sum_{i=1}^{n}|a[i]|leq 10^9)

    题解

    因为假如有(forall isum_{j=1}^{p-1} a_i),且(exists sum_{j=p}^na_j geq 0)

    最优解肯定不在(1-p-1)中,所以

    预处理几个东西(i是子集):

    (sum[i]:)状态为(i)时所有数的和

    (f[i]:)状态为(i)时和为(sum[i])的方案数

    (g[i]:)状态为(i)时排列为正的方案数

    转移看代码

    压行真舒服

    代码

    #include <iostream> 
    #include <cstdio> 
    using namespace std;
    #define rep(i, from, to) for(int i = (from); i <= (to); i++) 
    typedef long long ll; 
    const int Mod = 998244353; 
    int N, a[20], f[1 << 20], g[1 << 20]; 
    ll sum[1 << 20];
    void pls(int &x, int y) { x += y; if (x >= Mod) x -= Mod; } 
    int main () {
    	cin >> N; rep(i, 0, N - 1) cin >> a[i]; 
    	int S = (1 << N) - 1; 
    	g[0] = 1; 
    	rep (i, 0, N - 1) { f[1 << i] = 1; rep(s, 0, S) if (s & (1 << i)) sum[s] += a[i]; } 
    	rep (s, 0, S) { 
    		if (sum[s] > 0) rep (i, 0, N - 1) { if ((s & (1 << i)) == 0) pls(f[s | (1 << i)], f[s]); }
    		else rep (i, 0, N - 1) if (s & (1 << i)) pls(g[s], g[s ^ (1 << i)]); 
    	} 
    	rep (s, 0, S) { sum[s] %= Mod; while (sum[s] < 0) sum[s] += Mod; }
    	int ans = 0; rep (s, 0, S) pls(ans, 1ll * sum[s] * f[s] % Mod * g[S ^ s] % Mod); 
    	printf("%d
    ", ans); 
    	return 0; 
    } 
    
  • 相关阅读:
    【小强升职记】读书笔记
    MySQL HA 方案 MMM、MHA、MGR、PXC 对比
    【新机必备】
    【LeetCode】剑指 Offer 03. 数组中重复的数字
    生成表索引的创建和删除语句
    iptables 屏蔽端口
    mysql-5.6.20主从同步错误之Error_code: 1062 Duplicate entry '1' for key 'PRIMARY', Error_code: 1062
    OpenFeign和Consul爱恨交织的两天
    Docker:Linux离线安装docker-compose
    MySql:mysql命令行导入导出sql文件
  • 原文地址:https://www.cnblogs.com/heyujun/p/10288919.html
Copyright © 2011-2022 走看看