原文链接https://www.cnblogs.com/zhouzhendong/p/LOJ6433.html

题解

枚举一个集合 S ,表示最大前缀和中包含的元素集为 S ,然后求出有多少个排列是这样的。

对于左边和右边分别考虑,我们可以发现:

左边:每一个后缀和都 >=0

右边:每一个前缀和都 <0

然后就只需要用两个 dp 分别求出每一个集合的元素的排列中分别满足上述条件的方案数即可。

注意一下题目要求最大前缀和非空。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
int read(){
int x=0,f=1;
char ch=getchar();
while (!isdigit(ch)&&ch!='-')
ch=getchar();
if (ch=='-')
f=0,ch=getchar();
while (isdigit(ch))
x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return f?x:-x;
}
const int N=20,mod=998244353;
int n,a[N];
int Log[1<<N],sum[1<<N],dp1[1<<N],dp2[1<<N];
void Add(int &x,int y){
if ((x+=y)>=mod)
x-=mod;
}
int main(){
n=read();
for (int i=0;i<n;i++)
a[i]=read();
for (int i=2;i<(1<<n);i++)
Log[i]=Log[i>>1]+1;
for (int i=1;i<(1<<n);i++)
sum[i]=sum[i^(i&-i)]+a[Log[i&-i]];
dp1[0]=1;
for (int i=0;i<n;i++)
dp2[1<<i]=1;
for (int i=1;i<(1<<n);i++)
for (int j=0;j<n;j++)
if (i>>j&1){
if (sum[i]<0)
Add(dp1[i],dp1[i^(1<<j)]);
if (sum[i]-a[j]>=0)
Add(dp2[i],dp2[i^(1<<j)]);
}
int ans=0,base=(1<<n)-1;
for (int i=1;i<(1<<n);i++)
ans=(1LL*sum[i]*dp2[i]%mod*dp1[i^base]+ans)%mod;
ans=(ans+mod)%mod;
printf("%d",ans);
return 0;
}

  

LOJ#6433. 「PKUSC2018」最大前缀和 状压dp的更多相关文章

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

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

  2. loj 6433 「PKUSC2018」最大前缀和 题解【DP】【枚举】【二进制】【排列组合】

    这是个什么集合DP啊- 想过枚举断点但是不会处理接下来的问题了- 我好菜啊 题目描述 小 C 是一个算法竞赛爱好者,有一天小 C 遇到了一个非常难的问题:求一个序列的最大子段和. 但是小 C 并不会做 ...

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

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

  4. Loj#6433「PKUSC2018」最大前缀和(状态压缩DP)

    题面 Loj 题解 先转化题意,其实这题在乘了\(n!\)以后就变成了全排列中的最大前缀和的和(有点拗口).\(n\leq20\),考虑状压\(DP\) 考虑一个最大前缀和\(\sum\limits_ ...

  5. loj#6433. 「PKUSC2018」最大前缀和(状压dp)

    传送门 今天\(PKUWC\)试机的题 看着边上的大佬们一个个\(A\)穿咱还是不会-- 我们考虑枚举最大前缀和,如果一个前缀\(1\)到\(p\)是最大前缀和,那么\(p\)后面的所有前缀和都要小于 ...

  6. [LOJ #6433]「PKUSC2018」最大前缀和

    题目大意:给你一个$n(n\leqslant20)$项的数列$A$,设重排后的数列为$A'$,令$pre_p=\sum\limits_{i=1}^pA'_i$,求$max\{pre_i\}$的期望,乘 ...

  7. 【LOJ】#6433. 「PKUSC2018」最大前缀和

    题解 神仙的状压啊QAQ 设一个\(f[S]\)表示数字的集合为\(S\)时\(sum[S]\)为前缀最大值的方案数 \(g[S]\)表示数字集合为\(S\)时所有前缀和都小于等于0的方案数 答案就是 ...

  8. loj2540 「PKUWC2018」随机算法 【状压dp】

    题目链接 loj2540 题解 有一个朴素三进制状压\(dp\),考虑当前点三种状态:没考虑过,被选入集合,被排除 就有了\(O(n3^{n})\)的转移 但这样不优,我们考虑优化状态 设\(f[i] ...

  9. BZOJ1688 「USACO05OPEN」Disease Manangement 背包+状压DP

    问题描述 BZOJ1688 题解 背包,在转移过程中使用状压. \(\mathrm{Code}\) #include<bits/stdc++.h> using namespace std; ...

随机推荐

  1. ROM、PROM、EPROM、EEPROM、FLASH ROM简介

    ROM指的是"只读存储器",即Read-Only Memory.这是一种线路最简单半导体电路,通过掩模工艺, 一次性制造,其中的代码与数据将永久保存(除非坏掉),不能进行修改.这玩 ...

  2. JS如何截取一段字符中,某一个字符的前面和后面的字符

    比如这里的1992631934@qq.com如何获取到@前面的1992631934和@后面的qq.com js代码如下: var mail="1992631934@qq.com" ...

  3. Confluence 6 配置管理员联系页面

    管理员联系页面是一个格式化的页面,这个页面能够允许 Confluence 用户在 Confluence 中向管理员发送消息(在这部分的内容,管理员是默认管理员用户组的成员). 有关用户组的解释,请参考 ...

  4. leetcode(js)算法之17电话号码的字母组合

    给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合. 给出数字到字母的映射如下(与电话按键相同).注意 1 不对应任何字母 示例: 输入:"23" 输出:[" ...

  5. 《剑指offer》栈的插入弹出序列

    本题来自<剑指offer> 栈的插入弹出序列 题目: 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2, ...

  6. 关系代数和sql语句对应关系

    关系代数运算符 对应sql语句 聚合操作   ∪ (UNION)并   ∩ (INTERSECTION)交   -  (DIFFERENCE)差   × (Cartesian PRODUCT)笛卡尔积 ...

  7. bzoj 3191

    非常好的一道题 看到这道题,肯定能想到概率dp,但是状态的设计与转移都是一个难点 如果正向模拟来设计状态,那么不难发现是很难以转移的 所以我们考虑反向模拟,用类似博弈的方法来转移 不难发现,如果只剩了 ...

  8. 关于vue项目去除margin和padding后设置元素width和height为100%后,出现滚动条问题(移动端)

    bug点,这个页面设置100%(100vw和100vh).页面出现抖动. 经过一番检察,原因出现在,vue项目自动添加的一个div上.就是body里的最后一个.如果选中这个元素,右键删除它.页面就不会 ...

  9. 抓包工具Charles Proxy v4.1.1破解版下载

    移动开发抓包工具Charles Proxy破解版下载 下载Charles Proxy版本,http://charles.iiilab.com/或 https://www.charlesproxy.co ...

  10. 如何用TortoiseSVN对文件进行操作

    我们如何用TortoiseSVN修改文件,添加文件,删除文件,以及如何解决冲突等. 添加文件 在检出的工作副本中添加一个Readme.txt文本文件,这时候这个文本文件会显示为没有版本控制的状态,如图 ...