状态压缩

P5369

题意:求所有排列下的最大前缀和之和

一步转化: 求最大前缀和的前缀由数集S组成的方案数, 统计答案时直接乘上sum(S)即可

考虑最大前缀和的性质:

设最大前缀和为sum[i]

  1. 到i的后缀均为正数
  2. i后的前缀均为负数

令sum[i] = 集合 i 内所有数的和。

令f[i] = 集合 i内的数组成的排列,最大前缀和 = sum[i]的方案数。

令g[i] = 集合 i内的数组成的排列,所有的最大前缀和都 < 0 的方案数。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 25;
const int P = 998244353;
int n, a[N];
int f[1050050], g[1050050];
int sum[1050050];
inline int to(int x) {
return 1 << x;
}
int main() {
cin >> n; int all = to(n) - 1;
for (int i = 1;i <= n; i++)
cin >> a[i], f[to(i-1)] = 1, sum[to(i-1)] = a[i];
for (int i = 1;i <= all; i++)
sum[i] = sum[(i & -i)] + sum[i ^ (i & -i)];
g[0] = 1;
for (int i = 0;i < all; i++) {
if (sum[i] >= 0) {
for (int j = 1;j <= n; j++)
if (!(i & to(j-1)))
f[i | to(j-1)] = ((long long)f[i] + f[i | to(j-1)]) % P;
}
else {
for (int j = 1;j <= n; j++)
if (i & (to(j-1)))
g[i] = ((long long)g[i] + g[i ^ to(j-1)]) % P;
}
}
long long ans = 0;
for (int i = 1;i <= all; i++)
ans = (ans + (long long)f[i] * g[all^i] % P * sum[i] % P) % P;
cout << (ans % P + P) % P << endl;
return 0;
}

P5369 [PKUSC2018]最大前缀和的更多相关文章

  1. 洛谷P5369 [PKUSC2018]最大前缀和 [DP]

    传送门 思路 这么一道签到题竟然没切掉真是丢人呢-- 首先有一个\(O(3^n)\)的SB方法,记录\(dp_{S,T}\)表示已经填进去了\(S\),当前最大前缀和集合为\(T\),随便转移.太简单 ...

  2. [PKUSC2018]最大前缀和

    [PKUSC2018]最大前缀和 题目大意: 有\(n(n\le20)\)个数\(A_i(|A_i|\le10^9)\).求这\(n\)个数在随机打乱后最大前缀和的期望值与\(n!\)的积在模\(99 ...

  3. BZOJ_5369_[Pkusc2018]最大前缀和_状压DP

    BZOJ_5369_[Pkusc2018]最大前缀和_状压DP Description 小C是一个算法竞赛爱好者,有一天小C遇到了一个非常难的问题:求一个序列的最大子段和. 但是小C并不会做这个题,于 ...

  4. [PKUSC2018]最大前缀和——状压DP

    题目链接: [PKUSC2018]最大前缀和 设$f[S]$表示二进制状态为$S$的序列,任意前缀和都小于等于$0$的方案数. 设$g[S]$表示二进制状态为$S$的序列是整个序列的最大前缀和的方案数 ...

  5. LOJ6433 [PKUSC2018] 最大前缀和 【状压DP】

    题目分析: 容易想到若集合$S$为前缀时,$S$外的所有元素的排列的前缀是小于$0$的,DP可以做到,令排列前缀个数小于0的是g[S]. 令f[S]表示$S$是前缀,转移可以通过在前面插入元素完成. ...

  6. BZOJ5369:[PKUSC2018]最大前缀和(状压DP)

    Description 小C是一个算法竞赛爱好者,有一天小C遇到了一个非常难的问题:求一个序列的最大子段和. 但是小C并不会做这个题,于是小C决定把序列随机打乱,然后取序列的最大前缀和作为答案. 小C ...

  7. BZOJ5369 [Pkusc2018]最大前缀和

    题意 小C是一个算法竞赛爱好者,有一天小C遇到了一个非常难的问题:求一个序列的最大子段和. 但是小C并不会做这个题,于是小C决定把序列随机打乱,然后取序列的最大前缀和作为答案. 小C是一个非常有自知之 ...

  8. bzoj 5369: [Pkusc2018]最大前缀和

    Description 小C是一个算法竞赛爱好者,有一天小C遇到了一个非常难的问题:求一个序列的最大子段和. 但是小C并不会做这个题,于是小C决定把序列随机打乱,然后取序列的最大前缀和作为答案. 小C ...

  9. [PKUSC2018]最大前缀和(DP)

    题意:求一个序列随机打乱后最大前缀和的期望. 考场上发现不管怎么设状态都写不出来,实际上只要稍微转换一下就好了. 一个前缀[1..k]是最大前缀,当且仅当前面的所有后缀[k-1,k],[k-2,k], ...

随机推荐

  1. Python Web 之 Flask

    FLASK 一.概述 flask是一个基于python并依赖于Jinja2模板引擎和WerkZeug WSGI(Web Server Gatewey InterFace.web)服务的框架 WSGI: ...

  2. IdentityServer3学习记录(搭建IdentityServer项目)

    记录下自己尝试搭建identityServer3的过程,便于自己记录遗忘时翻看,也能便于刚接触的新手简单了解下搭建的过程. 更详细的可以参考 https://www.jianshu.com/p/792 ...

  3. 牛客多校第六场 C Generation I 组合数学 阶乘逆元模板

    链接:https://www.nowcoder.com/acm/contest/144/C来源:牛客网 Oak is given N empty and non-repeatable sets whi ...

  4. zoj 5823 Soldier Game 2018 青岛 I

    题目传送门 题意:现在有n个人,现在可以把这n个人分成若干组,只有连续的人才能被分为一组,并且一个组内最多2个人,现在问你 所有组内的最大值-最小值 这个差值最小是多少. 题解: 将每个人的情况3种情 ...

  5. 「每日五分钟,玩转JVM」:对象内存布局

    概览 一个对象根据不同情况可以被划分成两种情况,当对象是一个非数组对象的时候,对象头,实例数据,对齐填充在内存中三分天下,而数组对象中在对象头中多了一个用于描述数组对象长度的部分 对象头 对象头分为两 ...

  6. JSON和Map,List,String互相转换

    1)Map 和 JSON 互相转换 Map 转成 JSON Map<String, List> map = new HashMap<>(); map.put("xAx ...

  7. 019 模块2-time库的使用

    目录 一.概述 二.time库基本介绍 2.1 time库概述 三.时间获取 四.时间格式化 4.1 格式化控制符 4.2 时间格式化-代码 五.程序计时应用 5.1 程序计时 六.单元小结 参考:h ...

  8. Maven学习归纳(一)——简单的环境配置入门

    一.Maven的基本概念 Maven是基于项目对象模型(POM),可以通过一小段描述信息来管理项目的编译,测试,构建,报告和文档的软件项目管理工具和解决依赖关系的工具. 1.1 项目的构建 项目的构建 ...

  9. 使用openlivewriter编写cnblogs博客

    下载OpenLiveWriter 下载地址:http://openlivewriter.org/ 安装OpenLiveWriter 1.账号配置 2.常规操作,省略- 安装高亮插件 1.下载插件:ht ...

  10. Python(Head First)学习笔记:二

    2 共享代码:连接共享社区.语法.函数.技巧 通过Python模块共享代码,在Python社区分享这些模块,让更多的人受益, 不得不说,Python真的做的不错~ Python提供了一组技术,用于模块 ...