分析

我们让每个数列在第一个取到最大前缀和的位置被统计到。

假设一个数列在\(pos\)处第一次取到最大前缀和,分析性质,有:

  1. 下标在\([1,pos]\)之间的数形成的数列的每个后缀和(不包括整个数列,因为要求非空)都大于\(0\)。

  2. 下标在\([pos+1,n]\)之间的数形成的数列的每个前缀和(包括整个数列)都小于等于\(0\)。

正确性显然。

所以我们可以把数列从\(pos\)分成两部分,分别算出各自的方案数再相乘。

\([1,pos]\)部分

令\(f[S]\)表示\(S\)中的数形成的每个后缀和都大于\(0\)的数列个数,考虑每次向一个数后面加一个满足条件的数列,有状态转移方程:

\[f[\{i\}+S]+=f[S]\ (i \notin S,\ sum[S]>0)
\]

\([pos+1,n]\)部分

令\(g[S]\)表示\(S\)中的数形成的每个前缀和都小于等于\(0\)的数列个数,考虑每次向一个满足条件的数列后面加一个数,有状态转移方程:

\[g[S+\{i\}]+=g[S]\ (i \notin S,\ sum[S] \leq 0,\ sum[S+\{i\}] \leq 0)
\]

统计答案的话好像没什么好说的。

代码

#include <bits/stdc++.h>

#define rin(i,a,b) for(int i=(a);i<=(b);++i)
#define irin(i,a,b) for(int i=(a);i>=(b);--i)
#define trav(i,a) for(int i=head[a];i;i=e[i].nxt)
#define Size(a) (int)a.size()
#define pb push_back
#define mkpr std::make_pair
#define fi first
#define se second
#define lowbit(a) ((a)&(-(a)))
typedef long long LL; using std::cerr;
using std::endl; inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return x*f;
} const int MOD=998244353; int n,a[25],b[1<<20],f[1<<20],g[1<<20];
LL sum[1<<20]; inline int add(int x,int y){
return x+y<MOD?x+y:x+y-MOD;
} int main(){
n=read();
rin(i,1,n)a[i]=b[1<<(i-1)]=read(),f[1<<(i-1)]=1;
rin(i,1,(1<<n)-1)sum[i]=sum[i-lowbit(i)]+b[lowbit(i)];
rin(i,1,(1<<n)-1)if(sum[i]>0){
int r=(((1<<n)-1)^i);
while(r){
f[i|lowbit(r)]=add(f[i|lowbit(r)],f[i]);
r-=lowbit(r);
}
}
g[0]=1;
rin(i,0,(1<<n)-1)if(sum[i]<=0){
int r=(((1<<n)-1)^i);
while(r){
if(sum[i|lowbit(r)]<=0)g[i|lowbit(r)]=add(g[i|lowbit(r)],g[i]);
r-=lowbit(r);
}
}
int ans=0;
rin(i,0,(1<<n)-1)ans=(ans+1ll*sum[i]*f[i]%MOD*g[((1<<n)-1)^i])%MOD;
printf("%d\n",(ans%MOD+MOD)%MOD);
return 0;
}

[LOJ6433][PKUSC2018]最大前缀和:状压DP的更多相关文章

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

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

  2. 【PKUSC2018】【loj6433】最大前缀和 状压dp

    这题吼啊... 然而还是想了$2h$,写了$1h$. 我们发现一个性质:若一个序列$p$能作为前缀和,那么在序列$p$中,包含序列$p$最后一个数的所有子序列必然都是非负的. 那么,我们 令$f[i] ...

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

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

  4. LOJ#6433. 「PKUSC2018」最大前缀和 状压dp

    原文链接https://www.cnblogs.com/zhouzhendong/p/LOJ6433.html 题解 枚举一个集合 S ,表示最大前缀和中包含的元素集为 S ,然后求出有多少个排列是这 ...

  5. LOJ 6433 「PKUSC2018」最大前缀和——状压DP

    题目:https://loj.ac/problem/6433 想到一个方案中没有被选的后缀满足 “该后缀的任一前缀和 <=0 ”. 于是令 dp[ S ] 表示选了点集 S ,满足任一前缀和 & ...

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

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

  7. 「PKUSC2018」最大前缀和(状压dp)

    前言 考试被\(hyj\)吊着打... Solution 考虑一下如果前缀和如果在某一个位置的后面的任意一个前缀和都<=0,肯定这就是最大的. 然后这样子就考虑左右两边的状压dp,然后就好了. ...

  8. Loj 6433. 「PKUSC2018」最大前缀和 (状压dp)

    题面 Loj 题解 感觉挺难的啊- 状压\(dp\) 首先,有一个性质 对于一个序列的最大前缀和\(\sum_{i=1}^{p} A[i]\) 显然对于每个\(\sum_{i=p+1}^{x}A[i] ...

  9. 【洛谷5369】[PKUSC2018] 最大前缀和(状压DP)

    点此看题面 大致题意: 对于一个序列,求全排列下最大前缀和之和. 状压\(DP\) 考虑如果单纯按照题目中对于最大前缀和的定义,则一个序列它的最大前缀和是不唯一的. 为了方便统计,我们姑且规定,如果一 ...

  10. T2988 删除数字【状压Dp+前缀和优化】

    Online Judge:从Topcoder搬过来,具体哪一题不清楚 Label:状压Dp+前缀和优化 题目描述 给定两个数A和N,形成一个长度为N+1的序列,(A,A+1,A+2,...,A+N-1 ...

随机推荐

  1. ABCD 谁是小偷

    题目: 警察局抓了a,b,c,d 4名偷窃嫌疑犯,其中只有一人是小偷.审问中,a说:“我不是小偷.”b说:“c是小偷.”c说:“小偷肯定是d.”d说:“c在胡说.” 现在已经知道这四人中有三人说的是真 ...

  2. 部署k8s集群之环境搭建和etcd单节点安装

    环境搭建以及etcd 单节点安装过程 安装之前的环境搭建 在进行k8s安装之前先把虚拟机准备好,这里准备的是三台虚拟机 主机名 ip地址 角色 master 172.16.163.131 master ...

  3. 关于catopen函数

    关于catopen函数: 参考网址:http://pubs.opengroup.org/onlinepubs/009695399/functions/catopen.html 1)编辑消息文件 [ro ...

  4. Elasticsearch没看文档之前,整理的一些知识

    1 基础 index -> 数据库 type -> 表 document -> 行 field -> 列 ----------------------------------- ...

  5. 2019.10.9php进阶

    <?php header("Content-type:text/html;charset:utf-8"); if ($_FILES["file"][&qu ...

  6. gitlab和jenkins的安装及使用

    gitlab 准备: 最少4G内存 先安装docker软件包然后使用docker search gitlab 查找镜像然后使用docker pull 镜像名:标签名 下载镜像启动容器: docker ...

  7. 第五章 动画 50 动画-transition-group中appear和tag属性的作用

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...

  8. Mongodb中的js语法

    定义一个变量 > var len = 10; For循环 这里的db和data都可以作为对象 save是方法 接收一个临时定义的对象 > for(var i = 0; i < len ...

  9. The Preliminary Contest for ICPC Asia Nanchang 2019 B. Fire-Fighting Hero

    题目:https://nanti.jisuanke.com/t/41349 思路:dijkstra最短路径 先以 fire-fighting hero为起点 跑一遍dijkstra 建立 起点 p 并 ...

  10. 前端面试题-CSS Hack

    一.CSS Hack的概念 由于不同厂商的流览器或某浏览器的不同版本(如IE,Firefox/Safari/Opera/Chrome等),对CSS的支持.解析不一样,导致在不同浏览器的环境中呈现出不一 ...