[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]最大前缀和的更多相关文章

  1. [LOJ 6435][PKUSC 2018]星际穿越

    [LOJ 6435][PKUSC 2018]星际穿越 题意 给定 \(n\) 个点, 每个点与 \([l_i,i-1]\) 之间的点建立有单位距离的双向边. \(q\) 组询问从 \(x\) 走到 \ ...

  2. [LOJ 6432][PKUSC 2018]真实排名

    [LOJ 6432][PKUSC 2018]真实排名 题意 给定 \(n\) 个选手的成绩, 选中其中 \(k\) 个使他们的成绩翻倍. 对于每个选手回答有多少种方案使得他的排名不发生变化. \(n\ ...

  3. PKUSC 2018 题解

    PKUSC 2018 题解 Day 1 T1 真实排名 Link Solution 考虑对于每一个人单独算 每一个人有两种情况,翻倍和不翻倍,他的名次不变等价于大于等于他的人数不变 设当前考虑的人的成 ...

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

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

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

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

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

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

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

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

  8. 「PKUSC2018」最大前缀和 LOJ#6433&BZOJ5369

    分析: 这个题非常的棒,目测如果去了能AC... 我们考虑一个序列是如何构成的——一个后缀>0的序列,和一个前缀<0的序列 问题可以简化为求出当前缀和为状态S的所有数的和的时候,S满足后缀 ...

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

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

随机推荐

  1. CF1263F Economic Difficulties(DP)

    拿小号打了这场,然而做到这里时少看了条件,最后 10min 才发现,没有 AK,身败名裂-- 赛后看就是 sb 题-- (好像这题也不值 2500 吧?) 首先注意到一条很重要的条件:对于每棵树,都存 ...

  2. 网络编程实战之FTP的文件断点续传

    目录 一.项目地址 二.文件上传-断点续传 三.目录结构 四.client.py 五.server.py 5.1 文件的多种状态 六.conf/settings.py 七.lib/common.py ...

  3. 利器: Mac自带的图片工具Sips

    Sips是Mac提供的一个处理图片的命令行工具,与Photoshop这种重量级选手相比,自然功能上要差很多.不过话说回来如大小裁剪.图片翻转和旋转这些日常小功能其实也不必非得动用Photoshop这样 ...

  4. swoole进程间如何通信

    Swoole进程间通信的方式 管道pipe 管道用于进程之间的数据交互,Linux系统本身提供了pipe函数用于创建一个半双工通信管道.半双工的通信方式中数据只能单向流动(一端只读一端只写),只能在具 ...

  5. 《细说PHP》 第四版 样章 第二章 PHP的应用与发展 3

    2.3  PHP的开发优势 每种编程语言都有针对的领域,当然相同领域也有多个编程语言可以选择, 所以需要了解每种编程语言的优势和劣势,才能更好地去选择使用,在对的开发领域充分发挥它的优势,编写出最优质 ...

  6. javascript实现base64编码、解码

    我们知道,浏览器的window对象提供有window.atob()和window.btoa()方法可以对字符串进行Base64编码和解码. console.log(window.btoa(window ...

  7. 使用dapper遇到的问题及解决方法

    在使用dapper进行数据查询时遇到的一个问题,今天进行问题重现做一个记录,免得忘记以后又犯同样的错误. 自己要实现的是:select * from tablename where id in(1,2 ...

  8. gzip格式分析与识别

    " 介绍gzip格式,识别gzip压缩的数据流量." 在协议分析过程中,经常会发现gzip压缩的数据,例如在HTTP协议中,在HTTP头中会标示,内容编码为gzip.DEFLATE ...

  9. Xcode 7.3 解决自定义类无法自动联想

    正在苦拼的码友们,最近是不是觉得在写代码的时候很是头疼,甚至连个最基本的系统自带的语法啊.单词啊等等都不能联想了,之前习惯了的码友们,这个时候肯定会觉得是不是自己写错了,然后也往下翻了一大篇,还是找不 ...

  10. 剑指offer 16:反转链表

    题目描述 输入一个链表,反转链表后,输出新链表的表头. 解题思路 单链表原地反转是面试手撕代码环节非常经典的一个问题.针对一般单链表,反转的时候需要操作的是当前节点及与之相邻的其他两个节点.因而需要定 ...