bzoj5369: [Pkusc2018]最大前缀和

Description

小C是一个算法竞赛爱好者,有一天小C遇到了一个非常难的问题:求一个序列的最大子段和。
但是小C并不会做这个题,于是小C决定把序列随机打乱,然后取序列的最大前缀和作为答案。
小C是一个非常有自知之明的人,他知道自己的算法完全不对,所以并不关心正确率,他只关心求出的解的期望值,
现在请你帮他解决这个问题,由于答案可能非常复杂,所以你只需要输出答案乘上n!后对998244353取模的值,显然这是个整数。
注:最大前缀和的定义:i∈[1,n],Sigma(aj)的最大值,其中1<=j<=i

Input

第一行一个正整数nnn,表示序列长度。
第二行n个数,表示原序列a[1…n],第i个数表示a[i]。
1≤n≤20,Sigma(|Ai|)<=10^9,其中1<=i<=N

Output

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

Sample Input

2
-1 2

Sample Output

3

分析

考场不会写系列。
基本思路是状压sss,计算sum[s]sum[s]sum[s]作为最大前缀和的方案,其中sum[s]sum[s]sum[s]为状态sss各个数的和。
首先为了避免重复,如有多解,用下标最小的最大前缀和标记每种方案。
考虑一个前缀和S[1⋯p]S[1\cdots p]S[1⋯p]作为最大前缀和的等价条件。

  • 序列2⋯p2\cdots p2⋯p不存在小于等于0的后缀和。
  • 序列p+1⋯np+1\cdots np+1⋯n不存在大于0的前缀和。

必要性:假设存在大于0的前缀和或小于等于0的后缀和,考虑加上/减去那段前缀/后缀和,就一定找到了一个更加优秀的前缀和,矛盾。
充分性:假设一个更优秀的解,如果在ppp之后,两端前缀和作差必然得到一个序列p+1⋯np+1\cdots np+1⋯n的大于0的前缀和,在ppp之前同理,矛盾。
这两个条件的好处是他们将一个最优性问题转化成了判定性问题。这样提供了一个比较简便的转移思路。
同时发现这两个条件是独立的,前一个条件与后一个条件是两个独立的问题,于是我们可以把目标集合划分成两个部分,前一个部分满足条件1,将其作为前缀,后一个部分满足条件2,将其作为后缀,乘法原理即可计算方案数。
具体地,设f[s]f[s]f[s]表示集合sss为一个合法的满足条件1的前缀的方案数。枚举一个新的数xxx,如果这个数可以合法地放在sss最前,必有sum[s]&gt;0sum[s]&gt; 0sum[s]>0(满足条件1),类似地,设g[s]g[s]g[s]表示集合sss为一个合法的满足条件2的后缀的方案数,枚举一个新的数xxx,如果这个数可以合法地放在sss最后,则必有sum[s]+a[x]≤0sum[s]+a[x]\le 0sum[s]+a[x]≤0
最终的答案即为∑f[s]⋅g[all−s]\sum f[s]\cdot g[all - s]∑f[s]⋅g[all−s]

代码

#include<bits/stdc++.h>
const int P = 998244353, S = 1048576;
int ri() {char c = getchar(); int x = 0, f = 1; for(;c < '0' || c > '9'; c = getchar()) if(c == '-') f = -1;for(;c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) - '0' + c; return x * f;
}
int f[S], g[S], sum[S], bn[21], n;
void Up(int &a, int b) {a += b; a %= P;}
int main() {g[0] = bn[0] = 1; for(int i = 1;i <= 20; ++i) bn[i] = bn[i - 1] << 1;n = ri();for(int i = 0;i < n; ++i) {int x = ri(); f[bn[i]] = 1;for(int s = 0;s < bn[n]; ++s) if(s & bn[i]) sum[s] += x;}for(int s = 0;s < bn[n]; ++s) {if(sum[s] > 0) {for(int i = 0;i < n; ++i) if(~s & bn[i]) Up(f[s | bn[i]], f[s]);}else {for(int i = 0;i < n; ++i)if(s & bn[i]) Up(g[s], g[s ^ bn[i]]);}}int r = 0;for(int s = 0;s < bn[n]; ++s) Up(r, 1LL * sum[s] * f[s] % P * g[bn[n] - 1 ^ s] % P);printf("%d\n", (r + P) % P);return 0;
}

bzoj5369: [Pkusc2018]最大前缀和 状压Dp 计数Dp相关推荐

  1. 【训练题66:状压暴力 | 子集dp】Greater Integer, Better LCM | 2021牛客暑期多校训练营5

    题意 Greater Integer, Better LCM | 2021牛客暑期多校训练营5 给你 a,b,ca,b,ca,b,c ,你需要找到一对 x,yx,yx,y ,满足: lcm(a+x,b ...

  2. 2019 GDCPC or HDU6540 树形dp[计数dp] 详解

    题目链接 题目大意: 就是给你一颗nnn个点的树,树上有mmm个关键点,你可以选择若干个关键点组成集合SSS,这个集合满足任意两点在树上的距离不超过kkk,问你有多少种选法? 解题思路: 我们考虑树形 ...

  3. HDU 4336 Card Collector(状压 + 概率DP 期望)题解

    题意:每包干脆面可能开出卡或者什么都没有,一共n种卡,每种卡每包爆率pi,问收齐n种卡的期望 思路:期望求解公式为:$E(x) = \sum_{i=1}^{k}pi * xi + (1 - \sum_ ...

  4. Codeforces ----- Kefa and Dishes [状压dp]

    题目传送门:580D 题目大意:给你n道菜以及每道菜一个权值,k个条件,即第y道菜在第x道后马上吃有z的附加值,求从中取m道菜的最大权值 看到这道题,我们会想到去枚举,但是很显然这是会超时的,再一看数 ...

  5. ACM-ICPC 2018 南京赛区网络预赛 E.AC Challenge 状压dp

    题意: 给定n个作业,每个作业有两个值a,b, 第i天完成这个作业会得到value :i*a + b: 但是完成这个任务之前需要完成一些别的任务 思路: 乍一看像是搜索,但是似乎不太行(好像可以写过) ...

  6. ACM-ICPC 2018 南京赛区网络预赛丨AC Challenge丨状压DP

    题意: 一个人做n道题目,每道题会收获ai*t+bi的分数,同时要休息一个单位的时间t.此外,还限制做题目i之前,要先完成si道题目{pi1,pi2,···,pisi}求最多获得多少分数. 思路: n ...

  7. Codeforces 1741G 最短路上状压dp

    题意: 有 n n n个地方,他们被 m m m条道路相连.有一天, t o t tot tot个人在 1 1 1处开派对,开完派对他们要回家,他们回家只会走最短路径,其中有 k ( k ≤ 6 ) ...

  8. 【BZOJ】1076 [SCOI2008]奖励关 期望DP+状压DP

    [题意]n种宝物,k关游戏,每关游戏给出一种宝物,可捡可不捡.每种宝物有一个价值(有负数).每个宝物有前提宝物列表,必须在前面的关卡取得列表宝物才能捡起这个宝物,求期望收益.k<=100,n&l ...

  9. 2018 ICPC Asia Jakarta Regional Contest J. Future Generation 状压dp

    传送门 文章目录 题意: 思路: 题意: 给你nnn个串,字符集是a−za-za−z,让你在每个串种选择一个子序列,保证对于i<j,si<sji<j,s_i<s_ji<j ...

  10. 【BZOJ4416】阶乘字符串(SHOI2013)-状压DP

    测试地址:阶乘字符串 做法:本题需要用到状压DP. 首先,根据证明(直觉),满足条件的字符串的最小长度仅仅比n2n2n^2小一点点,因此当n>21n>21n>21时,直接输出NO即可 ...

最新文章

  1. 中国铁建内网漫游沦陷多个重要部门泄漏大量信息(redis+ssh-keygen免认证登录案例)...
  2. 2021年春季学期-信号与系统-第六次作业参考答案-第九小题
  3. 大话中文文本分类之DPCNN
  4. Linux下Dialog+Shell三层目录专业规范跳板机脚本
  5. python将2个列表list合并到1个列表使用appenden_【新手入门】20个很实用的 Python 学习小技巧...
  6. Erlang 位串和二进制数据
  7. dom4j的读写xml文件,读写xml字符串
  8. eclipse出现String错误,问题已解决
  9. 《我也能做CTO之程序员职业规划》之十:程序员职业规划就像软件工程
  10. 将keras的模型封装成可转换为tensorlow的.pb格式,并生成.pbtxt文件
  11. UDP数据包的产生和发送
  12. 修改服务器网卡速率,linux查看网卡速率命令(linux如何改网卡速率命令)
  13. 【laravel-admin】权限管理与实现原理
  14. Python正则表达式中的r
  15. “天成云”品牌发布——Tungsten Fabric助力开源开放生态发展
  16. 让人绝望的C语言恶搞小程序,网友:生无可恋!
  17. 转载:计算机视觉任务(Computer Vision)整理
  18. 一封来自前ThoughtWorks总监咨询师、致国内程序员的一封信
  19. JVM运行时内存结构学习
  20. 福利图网站的正确使用姿势

热门文章

  1. 三年出现三家上市企业 两轮电动车的生意好做吗?
  2. PPT转图片(Java)
  3. php 无限极分类树形图,ThinkPhp 实现 无限极分类及树状结构 附加使用例子
  4. 解决allegro 中OUT OF DATE SHAPES问题
  5. 反函数抽样(包括离散的)
  6. 【CTFhub】彩蛋篇_持续更新
  7. 药品名自动归类机器人(化药_中成药_中药材)
  8. android 旋转木马菜单,AndroidCarrouselLayout
  9. 论文发表费用一般是多少
  10. 算法设计实验一单峰序列