[LOJ 6433][PKUSC 2018]最大前缀和
[LOJ 6433][PKUSC 2018]最大前缀和
题意
给定一个长度为 \(n\) 的序列, 求把这个序列随机打乱后的最大前缀和的期望乘以 \(n!\) 后对 \(998244353\) 取膜后的值.
前缀和不能为空.
\(n\le 20\).
题解
首先这个期望显然是逗你玩的...只是计数而已
然后我们把一个序列拆成两部分, 一部分前缀和都不大于总和, 一部分前缀和都不大于 \(0\). 那么显然这样的一个序列的最大前缀和就是第一部分的和. 我们只要知道有多少个这样的序列就好了.
后面的做法感觉有点意思
我们用两个DP分别求解序列的某个子集组成两个部分的方案数量. 如果当前集合的和大于 \(0\) 那么显然不能用来组成第二部分, 但是我们可以在这个集合产生的合法第一部分的前面加一个值来组成新的第一部分. 而如果当前集合的和不大于 \(0\), 那么它只能用于构成第二部分, 而且我们可以断定如果在这个集合中钦定某个值放在最后, 那么只要剩下的值能构成合法的第二部分, 新的序列也能构成合法的第二部分.
最后枚举那些值在第一部分, 剩下值丢给第二部分, 卷起来就可以了.
参考代码
#include <bits/stdc++.h>
const int MAXN=21;
const int MOD=998244353;
const int MAXL=(1<<20)|3;
int n;
int a[MAXN];
int dp1[MAXL];
int dp2[MAXL];
int sum[MAXL];
inline int LowBit(int);
int main(){
scanf("%d",&n);
dp2[0]=1;
for(int i=0;i<n;i++){
scanf("%d",a+i);
dp1[1<<i]=1;
sum[1<<i]=a[i];
}
for(int s=1;s<(1<<n);s++){
if(s!=LowBit(s))
sum[s]=sum[s^LowBit(s)]+sum[LowBit(s)];
if(sum[s]>0){
for(int i=0;i<n;i++)
if((s&(1<<i))==0)
(dp1[s^(1<<i)]+=dp1[s])%=MOD;
}
else{
for(int i=0;i<n;i++)
if((s&(1<<i))!=0)
(dp2[s]+=dp2[s^(1<<i)])%=MOD;
}
}
int ans=0;
for(int s=1;s<(1<<n);s++)
(ans+=1ll*sum[s]*dp1[s]%MOD*dp2[((1<<n)-1)^s]%MOD)%=MOD;
printf("%d\n",ans<0?ans+MOD:ans);
return 0;
}
inline int LowBit(int x){
return x&-x;
}

[LOJ 6433][PKUSC 2018]最大前缀和的更多相关文章
- [LOJ 6435][PKUSC 2018]星际穿越
[LOJ 6435][PKUSC 2018]星际穿越 题意 给定 \(n\) 个点, 每个点与 \([l_i,i-1]\) 之间的点建立有单位距离的双向边. \(q\) 组询问从 \(x\) 走到 \ ...
- [LOJ 6432][PKUSC 2018]真实排名
[LOJ 6432][PKUSC 2018]真实排名 题意 给定 \(n\) 个选手的成绩, 选中其中 \(k\) 个使他们的成绩翻倍. 对于每个选手回答有多少种方案使得他的排名不发生变化. \(n\ ...
- PKUSC 2018 题解
PKUSC 2018 题解 Day 1 T1 真实排名 Link Solution 考虑对于每一个人单独算 每一个人有两种情况,翻倍和不翻倍,他的名次不变等价于大于等于他的人数不变 设当前考虑的人的成 ...
- LOJ 6433 「PKUSC2018」最大前缀和——状压DP
题目:https://loj.ac/problem/6433 想到一个方案中没有被选的后缀满足 “该后缀的任一前缀和 <=0 ”. 于是令 dp[ S ] 表示选了点集 S ,满足任一前缀和 & ...
- Loj#6433「PKUSC2018」最大前缀和(状态压缩DP)
题面 Loj 题解 先转化题意,其实这题在乘了\(n!\)以后就变成了全排列中的最大前缀和的和(有点拗口).\(n\leq20\),考虑状压\(DP\) 考虑一个最大前缀和\(\sum\limits_ ...
- Loj 6433. 「PKUSC2018」最大前缀和 (状压dp)
题面 Loj 题解 感觉挺难的啊- 状压\(dp\) 首先,有一个性质 对于一个序列的最大前缀和\(\sum_{i=1}^{p} A[i]\) 显然对于每个\(\sum_{i=p+1}^{x}A[i] ...
- LOJ#6433. 「PKUSC2018」最大前缀和 状压dp
原文链接https://www.cnblogs.com/zhouzhendong/p/LOJ6433.html 题解 枚举一个集合 S ,表示最大前缀和中包含的元素集为 S ,然后求出有多少个排列是这 ...
- 「PKUSC2018」最大前缀和 LOJ#6433&BZOJ5369
分析: 这个题非常的棒,目测如果去了能AC... 我们考虑一个序列是如何构成的——一个后缀>0的序列,和一个前缀<0的序列 问题可以简化为求出当前缀和为状态S的所有数的和的时候,S满足后缀 ...
- loj 6433 「PKUSC2018」最大前缀和 题解【DP】【枚举】【二进制】【排列组合】
这是个什么集合DP啊- 想过枚举断点但是不会处理接下来的问题了- 我好菜啊 题目描述 小 C 是一个算法竞赛爱好者,有一天小 C 遇到了一个非常难的问题:求一个序列的最大子段和. 但是小 C 并不会做 ...
随机推荐
- 趣谈Linux操作系统学习笔记:第二十九讲
一.引子 在这之前,有一点你需要注意.解析系统调用是了解内核架构最有力力的一把钥匙,这里我们只要重点关注这几个最重要的系统调用就可以了 1.mount 系统调用用于挂载文件系统:2.open 系统调用 ...
- Python程序中的进程操作-进程间通信(multiprocess.Queue)
目录 一.进程间通信 二.队列 2.1 概念介绍--multiprocess.Queue 2.1.1 方法介绍 2.1.2 其他方法(了解) 三.代码实例--multiprocess.Queue 3. ...
- html背景音乐
标签<audio> 参用属性 autoplay="autoplay"自动播放 controls="controls",在页面内显示显示控件,如播放按 ...
- PHP TP框架自定义打印函数P
效果如下,有个灰色背景,也不一定是灰色可以改 代码: //传递数据以易于阅读的样式格式化后输出function p($data){ // 定义样式 $str='<pre style=" ...
- Requests库主要方法解析以及Requests库入门需要掌握的框架
Requests库主要方法解析以及Requests库入门 1.requests.request(method,url,**kwargs) **kwargs:控制访问的参数,均为可选项 params:字 ...
- oracle学习笔记(二十三)——JDBC调用存储过程以及批量操作
jdbc调用存储过程 使用并获得out模式的参数返回值 //存储过程为sum_sal(deptno department.deptno%type,sum in out number) Callable ...
- 最近的项目系之3——core3.0整合Senparc
1.前言 既然是.net下微信开发,自然少不了Senparc,可以说这个框架的存在, 至少节省了微信相关工作量的80%.事实上,项目开始前,还纠结了下是Java还是core,之所以最终选择core,除 ...
- File文件的创建,删除 createNewFile() delete()
package seday03; import java.io.File;import java.io.IOException; /*** 使用File新建一个test1.txt文件* @author ...
- 【OOM】解决思路
一.什么是OOM? OOM就是outOfMemory,内存溢出!可能是每一个java人员都能遇到的问题!原因是堆中有太多的存活对象(GC-ROOT可达),占满了堆空间. 二.怎么解决? 1.拿到内存溢 ...
- 从实例一步一步入门学习SpringCloud的Eureka、Ribbon、Feign、熔断器、Zuul的简单使用(附代码下载)
场景 SpringCloud -创建统一的依赖管理: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/102530574 Sprin ...