【洛谷5369】[PKUSC2018] 最大前缀和(状压DP)
大致题意: 对于一个序列,求全排列下最大前缀和之和。
状压\(DP\)
考虑如果单纯按照题目中对于最大前缀和的定义,则一个序列它的最大前缀和是不唯一的。
为了方便统计,我们姑且规定,如果一个序列中存在多个最大前缀和,我们取最靠后的一个。
由此我们想到,对于一个序列可以把它分为两部分\([1,k]\)和\([k+1,n]\)满足:
- \([1,k]\)是\([1,k]\)本身的最大前缀和。
- \([k+1,n]\)内所有前缀和均小于\(0\)。
显然,由于\([1,k]\)是其本身的最大前缀和,而其之后每一段前缀和都小于\(0\),因此它就是整个序列的最大前缀和。
设\([1,k]\)区间的点集为\(i\),\(s_i\)为点集\(i\)内数的和(注意,此处的和不取模,要开\(long\ long\)存储),\(f_i\)为点集\(i\)排列成的序列是其本身的最大前缀和的方案数,\(g_i\)为点集\(i\)排列成的序列所有前缀和均小于\(0\)的方案数(易发现,\(f\)和\(g\)分别对应上面的两个条件)。
则答案就是\(\sum s_i\cdot f_i\cdot g_{2^{n-1}\ xor\ i}\)(结合前文自行理解)。
\(DP\)转移
考虑\(DP\)如何转移。
对于\(f_i\),我们可以枚举一个不在点集\(i\)中的点\(j\)。
如果把\(j\)放在点集\(i\)排列成的序列的最后面,显然不太好转移,也无法利用\(f\)本身的性质。
但如果我们把\(j\)放在点集\(i\)排列成的序列的最前面,则只要\(s_i\ge 0\),显然有:
- \(a_j\le a_j+s_i\)。
- 对于除\(a_j\)外的其他前缀\(sum\),由于在\(f_i\)中满足\(sum\le s_i\),所以\(a_j+sum\le a_j+s_i\)必然满足。
也就是说,在\(s_i\ge 0\)时,可以保证此时点集排列成的序列是其本身的最大前缀和。
因此,\(f_{i|2^{j-1}}+=f_i\)。
对于\(g_i\),我们同样枚举一个不在点集\(i\)中的点\(j\)。
与之前不同,这次我们可以直接把点\(j\)放在点集\(i\)排列成的序列的最后面。
因为在\(g_i\)中满足所有前缀和均小于\(0\),此时在序列最后面新添了一个点,并不会影响之前的前缀和。
而新添出的这个前缀和,就是这个序列的和,即\(s_{i|2^{j-1}}\)。
很显然,若要满足条件,当且仅当\(s_{i|2^{j-1}}<0\)。
也就是说,在\(s_{i|2^{j-1}}<0\)时,可以保证此时点集排列成的序列所有前缀和均小于\(0\)。
因此,\(g_{i|2^{j-1}}+=g_i\)。
代码
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 20
#define X 998244353
#define Inc(x,y) ((x+=(y))>=X&&(x-=X))
using namespace std;
int n,a[N+5],f[1<<N],g[1<<N];long long s[1<<N];
int main()
{
RI i,j,t,ans=0;for(scanf("%d",&n),i=1;i<=n;++i) scanf("%d",a+i);//读入
for(t=1<<n,i=0;i^t;++i) for(j=1;j<=n;++j) (i>>j-1)&1&&(s[i]+=a[j]);//预处理s[i]
for(f[0]=1,i=0;i^t;++i) for(j=1;j<=n;++j) !((i>>j-1)&1)&&s[i]>=0&&Inc(f[i|(1<<j-1)],f[i]);//DP转移f[i]
for(g[0]=1,i=0;i^t;++i) for(j=1;j<=n;++j) !((i>>j-1)&1)&&s[i|(1<<j-1)]<0&&Inc(g[i|(1<<j-1)],g[i]);//DP转移g[i]
for(i=0;i^t;++i) ans=((s[i]%X+X)%X*f[i]%X*g[(t-1)^i]+ans)%X;return printf("%d",ans),0;//统计答案
}
【洛谷5369】[PKUSC2018] 最大前缀和(状压DP)的更多相关文章
- 【题解】洛谷P2704 [NOI2001] 炮兵阵地(状压DP)
洛谷P2704:https://www.luogu.org/problemnew/show/P2704 思路 这道题一开始以为是什么基于状压的高端算法 没想到只是一道加了一行状态判断的状压DP而已 与 ...
- 【题解】洛谷P1896 [SCOI2005] 互不侵犯(状压DP)
洛谷P1896:https://www.luogu.org/problemnew/show/P1896 前言 这是一道状压DP的经典题 原来已经做过了 但是快要NOIP 复习一波 关于一些位运算的知识 ...
- 洛谷P1171 售货员的难题【状压DP】
题目描述 某乡有n个村庄(1 输入格式: 村庄数n和各村之间的路程(均是整数). 输出格式: 最短的路程. 输入样例: 3 0 2 1 1 0 2 2 1 0 输出样例 3 说明 输入解释 3 {村庄 ...
- 2018.07.18 洛谷P1171 售货员的难题(状压dp)
传送门 感觉是一道经典的状压dp,随便写了一发卡了卡常数开了个O(2)" role="presentation" style="position: relati ...
- 洛谷P2761 软件补丁问题(状压dp)
传送门 啊咧……这题不是网络流二十四题么……为啥是个状压dp…… 把每一个漏洞看成一个状态,直接硬上状压dp 然后因为有后效型,得用spfa //minamoto #include<iostre ...
- 洛谷$P3226\ [HNOI2012]$集合选数 状压$dp$
正解:$dp$ 解题报告: 传送门$QwQ$ 考虑列一个横坐标为比值为2的等比数列,纵坐标为比值为3的等比数列的表格.发现每个数要选就等价于它的上下左右不能选. 于是就是个状压$dp$板子了$QwQ$ ...
- 洛谷 P2622 关灯问题II【状压DP】
传送门:https://www.luogu.org/problemnew/show/P2622 题面: 题目描述 现有n盏灯,以及m个按钮.每个按钮可以同时控制这n盏灯--按下了第i个按钮,对于所有的 ...
- UOJ #129 / BZOJ 4197 / 洛谷 P2150 - [NOI2015]寿司晚宴 (状压dp+数论+容斥)
题面传送门 题意: 你有一个集合 \(S={2,3,\dots,n}\) 你要选择两个集合 \(A\) 和 \(B\),满足: \(A \subseteq S\),\(B \subseteq S\), ...
- 洛谷 P6499 - [COCI2016-2017#2] Burza(状压 dp)
题面传送门 一道挺有意思的思维题(?) 首先我们假设根节点深度为 \(0\),那么 Daniel 的目标显然就是堵住一些节点使得 Stjepan 不能移动到深度为 \(k\) 的节点,Stjepan ...
- 洛谷 P7620 - CF1431J Zero-XOR Array(状压 dp)
洛谷题面传送门 首先显然题目等价于求有多少个长度 \(n-1\) 的序列 \(b\) 满足 \(a_i\le b_i\le a_{i+1}\),满足 \(b_1\oplus b_2\oplus\cdo ...
随机推荐
- Django 07
目录 ORM查询优化 only与defer(单表) select_related与prefetch_related(跨表) choices参数 MTV与MVC模型 Ajax简介 前后端传输数据编码格式 ...
- elasticsearch搜索QueryStringQueryBuilder时的一些问题记录
首先看下原始数据 但是 如果使用英文查询的时候又和上面有点区别了,感觉还是分词器的问题
- Webpack基础知识总结
本文将从多个方面回顾下自己了解的Webpack知识,包括常见的配置项,前端搭建的一些方法和项目实际优化方法,有错误的地方还请指出并多多包涵. 一.关于Webpack 1.概念 本质上,webpack ...
- JS基础-正则
正则表达式 创建正则表达式 使用一个正则表达式字面量 const regex = /^[a-zA-Z]+[0-9]*\W?_$/gi; 调用RegExp对象的构造函数 const regex = ne ...
- 使用脚本安装 Docker
使用脚本安装 Docker 1.使用 sudo 或 root 权限登录 Centos. 2.确保 yum 包更新到最新. $ sudo yum update 3.执行 Docker 安装脚本. $ c ...
- 【玩转SpringBoot】看似复杂的Environment其实很简单
喜欢写代码,讨厌配环境 我相信这十个字的小标题代表了大多数码农的心声. 十年前读大学时,学校开设了C语言还有C++.但是学习这两种语言,对于新手来说非常没有成就感. 于是我就在校门口买个光盘,装个VS ...
- Django聚合查询 orm字段及属性
目录 一 聚合查询 1. 级联 级联删除 级联更新 2. 聚合函数 使用 aggregate 使用场景 3. 分组查询 语法 使用 annotate 代码 4. F与Q查询 F查询 Q查询 二 ORM ...
- 《Java基础知识》Java多态和动态绑定
在Java中,父类的变量可以引用父类的实例,也可以引用子类的实例. 请读者先看一段代码: public class Demo { public static void main(String[] ar ...
- Docker中Nginx服务器相关配置
工作中经常需要在服务器上来做一下实验,亲自动手看看效果是否与理论描述的相同.用docker可以很方便的配置所需要的环境,以下内容记录了如何用docker配置一个nginx服务器 下载nginx 从默认 ...
- Python基础-day01-2
第一个 Python 程序 目标 第一个 HelloPython 程序 Python 2.x 与 3.x 版本简介 执行 Python 程序的三种方式 解释器 -- python / python ...