点此看题面

大致题意: 对于一个序列,求全排列下最大前缀和之和。

状压\(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)的更多相关文章

  1. 【题解】洛谷P2704 [NOI2001] 炮兵阵地(状压DP)

    洛谷P2704:https://www.luogu.org/problemnew/show/P2704 思路 这道题一开始以为是什么基于状压的高端算法 没想到只是一道加了一行状态判断的状压DP而已 与 ...

  2. 【题解】洛谷P1896 [SCOI2005] 互不侵犯(状压DP)

    洛谷P1896:https://www.luogu.org/problemnew/show/P1896 前言 这是一道状压DP的经典题 原来已经做过了 但是快要NOIP 复习一波 关于一些位运算的知识 ...

  3. 洛谷P1171 售货员的难题【状压DP】

    题目描述 某乡有n个村庄(1 输入格式: 村庄数n和各村之间的路程(均是整数). 输出格式: 最短的路程. 输入样例: 3 0 2 1 1 0 2 2 1 0 输出样例 3 说明 输入解释 3 {村庄 ...

  4. 2018.07.18 洛谷P1171 售货员的难题(状压dp)

    传送门 感觉是一道经典的状压dp,随便写了一发卡了卡常数开了个O(2)" role="presentation" style="position: relati ...

  5. 洛谷P2761 软件补丁问题(状压dp)

    传送门 啊咧……这题不是网络流二十四题么……为啥是个状压dp…… 把每一个漏洞看成一个状态,直接硬上状压dp 然后因为有后效型,得用spfa //minamoto #include<iostre ...

  6. 洛谷$P3226\ [HNOI2012]$集合选数 状压$dp$

    正解:$dp$ 解题报告: 传送门$QwQ$ 考虑列一个横坐标为比值为2的等比数列,纵坐标为比值为3的等比数列的表格.发现每个数要选就等价于它的上下左右不能选. 于是就是个状压$dp$板子了$QwQ$ ...

  7. 洛谷 P2622 关灯问题II【状压DP】

    传送门:https://www.luogu.org/problemnew/show/P2622 题面: 题目描述 现有n盏灯,以及m个按钮.每个按钮可以同时控制这n盏灯--按下了第i个按钮,对于所有的 ...

  8. UOJ #129 / BZOJ 4197 / 洛谷 P2150 - [NOI2015]寿司晚宴 (状压dp+数论+容斥)

    题面传送门 题意: 你有一个集合 \(S={2,3,\dots,n}\) 你要选择两个集合 \(A\) 和 \(B\),满足: \(A \subseteq S\),\(B \subseteq S\), ...

  9. 洛谷 P6499 - [COCI2016-2017#2] Burza(状压 dp)

    题面传送门 一道挺有意思的思维题(?) 首先我们假设根节点深度为 \(0\),那么 Daniel 的目标显然就是堵住一些节点使得 Stjepan 不能移动到深度为 \(k\) 的节点,Stjepan ...

  10. 洛谷 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 ...

随机推荐

  1. Java 将Excel转为图片、html、XPS、XML、CSV

    通过文档格式转换,可满足不同办公场合对文档操作的需求.本文将介绍转换Excel文档为其他常见文档格式的方法.通过文中的方法,可支持将Excel转换为包括PDF.图片.html.XPS.XML.CSV. ...

  2. JavaEE基础(05):过滤器、监听器、拦截器,应用详解

    本文源码:GitHub·点这里 || GitEE·点这里 一.Listener监听器 1.概念简介 JavaWeb三大组件:Servlet,Listener,Filter.监听器就是指在应用程序中监听 ...

  3. JS基础知识点——原始类型和对象类型的区别

    1.js类型 1.1 JavaScript语言规定了7种语言类型,他们分别是: Number(数字) Boolean(布尔值) String(字符串) Null (空) Undefined (未定义) ...

  4. CSS预处理器之less和sass

    CSS预处理器 1.        基于CSS的另一种语言 2.        通过工具编译成CSS 3.        添加了很多CSS不具备的特性 4.        能提升CSS文件的组织方式 ...

  5. Oracle用户、角色、权限

    一.Oracle权限 系统权限:系统规定用户使用数据库的权限.(系统权限是对用户而言) 对象权限:某种权限用户对其它用户的表或视图的存取权限.(是针对表或视图而言的) 1.Oracle系统权限 ​ o ...

  6. C语言每日一练——第4题

    一.题目要求 已知数据文件in.dat中有300个四位数,并调用readDat()函数把这些数存储数组a中,编写函数jsValue(),其功能是:求出所有这些四位数是素数的个数cnt,再把所有满足此条 ...

  7. 1、采用SD启动盘bootingLinux

    一.准备条件 1.Arrow Sockit 开发板: 2.主机:可以是Linux系统,也可以是windows系统: 3.可以让主机识别的SD卡,不管是用读卡器还是用主机上的卡槽,内存4G以上 二.创建 ...

  8. Django项目BBS博客论坛

    BBS 项目开发逻辑梳理 第一步:先进行数据库设计 数据库设计规则是: 1.先创建基表:用户表.站点表.文章表.标签表.分类表.文章2标签第三张关系表.点赞点踩表.评论表 2.书写表中的基本含有的字段 ...

  9. LeetCode刷题总结-栈、链表、堆和队列篇

    本文介绍LeetCode上有关栈.链表.堆和队列相关的算法题的考点,推荐刷题20道.具体考点分类如下图: 一.栈 1.数学问题 题号:85. 最大矩形,难度困难 题号:224. 基本计算器,难度困难 ...

  10. crontab 定时任务没有响应 检测步骤

    设置规则 # 每分钟执行一次 */1 * * * * /scripts/script.sh # 每小时执行一次 0 */1 * * * /scripts/script.sh # 每天 02:00 执行 ...