正题

题目链接:https://www.luogu.com.cn/problem/P5369


题目大意

一个数列\(a\)的权值定义为\(max\{\sum_{i=1}^ka_i\}(k\in[1,n])\)

给出\(n\)个数字,求它们所有排列的权值和

\(1\leq n\leq 20\)


解题思路

设\(s_i,f_i,g_i\)分别表示集合\(i\)的权值和,集合\(i\)的所有排列中最大前缀和为\(s_i\)的方案数,集合\(i\)的所有排列中的最大前缀和为负的方案数。那么答案就是

\[\sum_{i=0}^{2^n-1} f_is_ig_{2^n-1-i}
\]

\(s_i\)很好求。\(g_i\)的话我们只转移\(s_i<0\)的就可以了,\(f_i\)的话我们考虑每次在前面插入一个数,那么只要原来的是最大前缀和,那么插入之后也一定是。

时间复杂度\(O(2^nn)\)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=21,P=998244353;
int n,a[N],lg[1<<N],s[1<<N],f[1<<N],g[1<<N],ans;
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%d",&a[i]);
for(int i=0;i<n;i++)lg[1<<i]=i;
int MS=(1<<n);f[0]=g[0]=1;
for(int i=1;i<MS;i++){
int p=i&-i;
s[i]=(s[i-p]+a[lg[p]])%P;
}
for(int i=0;i<MS;i++){
if(s[i]<0)continue;
for(int j=0;j<n;j++){
if(i&(1<<j))continue;
(f[i|(1<<j)]+=f[i])%=P;
}
}
for(int i=0;i<MS;i++){
for(int j=0;j<n;j++){
if(i&(1<<j))continue;
int z=i|(1<<j);
if(s[z]<0)(g[z]+=g[i])%=P;
}
}
for(int i=0;i<MS;i++)
(ans+=1ll*f[i]*g[MS-1-i]%P*s[i]%P)%=P;
printf("%d\n",(ans+P)%P);
return 0;
}

P5369-[PKUSC2018]最大前缀和【状压dp】的更多相关文章

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

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

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

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

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

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

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

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

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

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

  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. Spring-Boot的动态代理AOP原理

    前言 Spring AOP使用了动态代理技术,动态代理在业界比较流行的实现方式有,CGLIB,Javassist,ASM等等. Spring动态代理实现方式 Spring采用了JDK和CGLIB两种方 ...

  2. LeetCoded第739题题解--每日温度

    每日温度 请根据每日 气温 列表,重新生成一个列表.对应位置的输出为:要想观测到更高的气温,至少需要等待的天数.如果气温在这之后都不会升高,请在该位置用 0 来代替. 例如,给定一个列表 temper ...

  3. 辗转相除 求最大公约数!or 最小公倍数

    求最大公约数和最小公倍数的经典算法--辗转相除法描述如下: 若要求a,b两数的最大公约数和最小公倍数,令a为a.b中较大数,b为较小数,算法进一步流程: while(b不为0) { temp=a%b: ...

  4. 输入URL后浏览器的过程

    In this article, I want my readers to get a picture of a very basic concept of the web world. Previo ...

  5. session.flush与transaction.commit

    以session的save方法为例来看一个简单.完整的事务流程,如下是代码片段: ---------------------------- Session session = sessionFacto ...

  6. vue 优化hash持久化缓存

    公司用的是vue最近在学习react的打包时发现react会额外生成一个runtimeChunk,不知道具体原因所以查资料学习了下, 这里是runtime的功能,文章地址:https://sebast ...

  7. vue@cli3 public目录下的静态图片,如何使用在css类文件中(sass可行,纯css不行)

    之前写了一篇vue文件怎么使用的文章,有人问我怎么在css文件中使用public下的文件,这是个好问题,因为我之前都没有研究过 需要解决的2个问题 一开始按照vue文件的使用方式(https://ww ...

  8. 设置 ajax 同步获取数据

    问题 在处理DataTable的render进行列表渲染的时候发现通过ajax发送请求,返回的值并不正确. {"data":"id","render& ...

  9. MySQL(四)——

    MySQL官方对索引的定义:索引(Index)是帮助MySQL高效获取数据的数据结构.因此索引的本质就是数据结构.索引的目的在于提高查询效率,可类比字典.书籍的目录等这种形式. 可简单理解为" ...

  10. Python PIL、Pillow笔记

    原文链接:https://blog.csdn.net/FlashKoala/article/details/90649464 一.PIL.Pillow简介 PIL(Python Imaging Lib ...