BZOJ5369 [Pkusc2018]最大前缀和
题意
小C是一个算法竞赛爱好者,有一天小C遇到了一个非常难的问题:求一个序列的最大子段和。
但是小C并不会做这个题,于是小C决定把序列随机打乱,然后取序列的最大前缀和作为答案。
小C是一个非常有自知之明的人,他知道自己的算法完全不对,所以并不关心正确率,他只关心求出的解的期望值,
现在请你帮他解决这个问题,由于答案可能非常复杂,所以你只需要输出答案乘上n!后对998244353取模的值,显然这是个整数。
注:最大前缀和的定义:i∈[1,n],Sigma(aj)的最大值,其中1<=j<=i
\(n \leq 20\)
分析
乘上\(n!\),所谓期望其实就是每种最大前缀和乘上方案数的乘积的和。
参照Boss.Pi的题解。
看数据范围,考虑状压dp。注意到前缀和的取值只有 \(2^n\) 种.
然后可以枚举每一个集合的元素当最大前缀和 , 那么这个集合的元素排列之后每一个后缀都必须大于 \(0\) , 且这个集合的补集排列之后必须保证每一个前缀和都小于 \(0\).
那么状压 DP 就行了 , 设 \(f[i]\) 表示集合 \(i\) 作为最大前缀和且排列之后每个后缀都大于 \(0\) 的方案数 , \(g[i]\) 表示集合 \(i\) 中元素排列之后每个前缀都小于 \(0\) 的方案数.
强制 \(f,g\) 必须在合法的时候才能转移就行了.
时间复杂度\(O(n 2^n)\)
关于转移的问题
就算f加上j转移到了不合法的状态,以后也不会用到。
所以是对的。
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<algorithm>
#include<bitset>
#include<cassert>
#include<ctime>
#include<cstring>
#define rg register
#define il inline
#define co const
template<class T>il T read()
{
rg T data=0;
rg int w=1;
rg char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
w=-1;
ch=getchar();
}
while(isdigit(ch))
{
data=data*10+ch-'0';
ch=getchar();
}
return data*w;
}
template<class T>T read(T&x)
{
return x=read<T>();
}
using namespace std;
typedef long long ll;
co int N=22,mod=998244353;
int n;
int a[N];
int sum[1<<N],f[1<<N],g[1<<N];
il int add(int x,int y)
{
return (x+y)%mod;
}
il int mul(int x,int y)
{
return (ll)x*y%mod;
}
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
read(n);
for(int i=0;i<n;++i)
read(sum[1<<i]);
#define lowbit(x) (x&-x)
for(int i=0;i<(1<<n);++i)
sum[i]=sum[i-lowbit(i)]+sum[lowbit(i)];
for(int i=0;i<n;++i)
f[1<<i]=1,g[1<<i]=1;
for(int i=0;i<(1<<n);++i)
{
if(sum[i]>0)
{ // edit 1: the big brace is important
for(int j=0;j<n;++j)
if(~i>>j&1)
f[i|(1<<j)]=add(f[i|(1<<j)],f[i]);
}
else
{
for(int j=0;j<n;++j)
if(~i>>j&1)
g[i|(1<<j)]=add(g[i|(1<<j)],g[i]);
}
}
g[0]=1;
int ans=0;
for(int i=0;i<(1<<n);++i)
if(sum[((1<<n)-1)^i]<=0)
ans=add(ans,mul(f[i],mul(sum[i],g[((1<<n)-1)^i])));
printf("%d",(ans+mod)%mod);
return 0;
}
Hint
大括号的问题,害得我交了23次。
BZOJ5369 [Pkusc2018]最大前缀和的更多相关文章
- BZOJ5369:[PKUSC2018]最大前缀和(状压DP)
Description 小C是一个算法竞赛爱好者,有一天小C遇到了一个非常难的问题:求一个序列的最大子段和. 但是小C并不会做这个题,于是小C决定把序列随机打乱,然后取序列的最大前缀和作为答案. 小C ...
- [PKUSC2018]最大前缀和
[PKUSC2018]最大前缀和 题目大意: 有\(n(n\le20)\)个数\(A_i(|A_i|\le10^9)\).求这\(n\)个数在随机打乱后最大前缀和的期望值与\(n!\)的积在模\(99 ...
- BZOJ_5369_[Pkusc2018]最大前缀和_状压DP
BZOJ_5369_[Pkusc2018]最大前缀和_状压DP Description 小C是一个算法竞赛爱好者,有一天小C遇到了一个非常难的问题:求一个序列的最大子段和. 但是小C并不会做这个题,于 ...
- [PKUSC2018]最大前缀和——状压DP
题目链接: [PKUSC2018]最大前缀和 设$f[S]$表示二进制状态为$S$的序列,任意前缀和都小于等于$0$的方案数. 设$g[S]$表示二进制状态为$S$的序列是整个序列的最大前缀和的方案数 ...
- LOJ6433 [PKUSC2018] 最大前缀和 【状压DP】
题目分析: 容易想到若集合$S$为前缀时,$S$外的所有元素的排列的前缀是小于$0$的,DP可以做到,令排列前缀个数小于0的是g[S]. 令f[S]表示$S$是前缀,转移可以通过在前面插入元素完成. ...
- bzoj 5369: [Pkusc2018]最大前缀和
Description 小C是一个算法竞赛爱好者,有一天小C遇到了一个非常难的问题:求一个序列的最大子段和. 但是小C并不会做这个题,于是小C决定把序列随机打乱,然后取序列的最大前缀和作为答案. 小C ...
- [PKUSC2018]最大前缀和(DP)
题意:求一个序列随机打乱后最大前缀和的期望. 考场上发现不管怎么设状态都写不出来,实际上只要稍微转换一下就好了. 一个前缀[1..k]是最大前缀,当且仅当前面的所有后缀[k-1,k],[k-2,k], ...
- P5369 [PKUSC2018]最大前缀和
状态压缩 P5369 题意:求所有排列下的最大前缀和之和 一步转化: 求最大前缀和的前缀由数集S组成的方案数, 统计答案时直接乘上sum(S)即可 考虑最大前缀和的性质: 设最大前缀和为sum[i] ...
- 【洛谷5369】[PKUSC2018] 最大前缀和(状压DP)
点此看题面 大致题意: 对于一个序列,求全排列下最大前缀和之和. 状压\(DP\) 考虑如果单纯按照题目中对于最大前缀和的定义,则一个序列它的最大前缀和是不唯一的. 为了方便统计,我们姑且规定,如果一 ...
随机推荐
- HTML DOM(二):节点的增删改查
上一篇讲述了DOM的基本知识,从其得知,在DOM眼中,HTML的每个成分都可以看作是节点(文档节点.元素节点.文本节点.属性节点.注释节点,其中,属性节点是属于元素节点),本篇的内容就是通过DOM对这 ...
- 以普通用户启动的Vim如何保存需要root权限的文件
在Linux上工作的朋友很可能遇到过这样一种情况,当你用Vim编辑完一个文件时,运行:wq保存退出,突然蹦出一个错误: E45: 'readonly' option is set (add ! to ...
- raid write back / write throught
RAID write back指的是raid控制器能够将写入的数据写入自己的缓存中,并把它们安排到后续再执行,这样做的好处就是不需要等实际写入磁盘再返回,因此写入更快.对于数据库而言,这一点更为重要, ...
- Linux SSH隧道技术(端口转发,socket代理)
动态转发(SOCKS5代理): 命令格式:ssh -D <local port> <SSH Server> ssh -fnND 0.0.0.0:20058 172.16.50. ...
- opencv颜色提取color filting
# -*- coding: utf-8 -* import numpy as np import cv2 cap = cv2.VideoCapture(0) while True: _ , frame ...
- 大白话,讲编程之《ES6系列连载》汇总
如果你经历过2,3年前的前端开发,你一定感受过兼容IE6,7的痛苦,一定用过网页三剑客的dreamweaver编写html,面试的时候面试官一定会问你:会用PS切图吗? 刚开始的时候你发现,web前端 ...
- httplib模块,测试cdn节点文件同步
httplib模块是一个专门用于http的模块,urllib和urllib2也都是基于对它进行了更上层次的封装 我记得刚开始的时候,公司用的cdn有段时间抽风,全球40多个节点总是有那么几个节点不同步 ...
- python爬取商品信息
老严要爬某网购网站的商品信息,正好我最近在学python,就一起写了一个简单的爬虫程序. 需求:某网的商品信息,包括商品名,市场价和售价 工具:python2.7.8,urllib2,re #codi ...
- PHP Socket(套接字连接)扩展简介和使用方法
PHP socket扩展是基于流行的BSD sockets,实现了和socket通讯功能的底层接口,它可以和客户端一样当做一个socket服务器. 使用这些函数时请注意,虽然他们中有很多和C函数同名的 ...
- recovery.conf文件详解
在恢复过程中,用户可以通过使用recovery.conf文件来指定恢复的各个参数,如下: 归档恢复设置 restore_command:用于获取一个已归档段的XLOG日志文件的命令 archive_c ...