Description

小C是一个算法竞赛爱好者,有一天小C遇到了一个非常难的问题:求一个序列的最大子段和。

但是小C并不会做这个题,于是小C决定把序列随机打乱,然后取序列的最大前缀和作为答案。

小C是一个非常有自知之明的人,他知道自己的算法完全不对,所以并不关心正确率,他只关心求出的解的期望值,

现在请你帮他解决这个问题,由于答案可能非常复杂,所以你只需要输出答案乘上n!后对998244353取模的值,显然这是个整数。

注:最大前缀和的定义:i∈[1,n],Sigma(aj)的最大值,其中1<=j<=i

Solution

注意到前缀和的取值只有 \(2^n\) 种.

然后可以枚举每一个集合的元素当最大前缀和 , 那么这个集合的元素排列之后每一个后缀都必须大于 \(0\) , 且这个集合的补集排列之后必须保证每一个前缀和都小于 \(0\).

那么状压 \(DP\) 就行了 , 设 \(f[i]\) 表示集合 \(i\) 作为最大前缀和且排列之后每个后缀都大于 \(0\) 的方案数 , \(g[i]\) 表示集合 \(i\) 中元素排列之后每个前缀都小于 \(0\) 的方案数.

强制 \(f,g\) 必须在合法的时候才能转移就行了.

#include<bits/stdc++.h>
using namespace std;
const int N=25,mod=998244353;
int f[1<<20],n,a[N],m,g[1<<20],sum[1<<20];
int main(){
freopen("pp.in","r",stdin);
freopen("pp.out","w",stdout);
cin>>n,m=(1<<n)-1;
for(int i=0;i<n;i++)cin>>a[i];
for(int i=0;i<n;i++)
for(int j=0;j<=m;j++)if(j>>i&1)sum[j]+=a[i];
for(int i=0;i<n;i++)f[1<<i]=1,g[1<<i]=1;
for(int i=0;i<=m;i++){
if(sum[i]>0){
for(int j=0;j<n;j++)
if(~i>>j&1)f[i^(1<<j)]=(f[i^(1<<j)]+f[i])%mod;
}
else{
for(int j=0;j<n;j++)
if(~i>>j&1)g[i^(1<<j)]=(g[i^(1<<j)]+g[i])%mod;
}
}
g[0]=1;
int ans=0;
for(int i=0;i<=m;i++)
if(sum[m^i]<=0)ans=(ans+1ll*f[i]*sum[i]%mod*g[m^i])%mod;
cout<<(ans+mod)%mod;
return 0;
}

bzoj 5369: [Pkusc2018]最大前缀和的更多相关文章

  1. [PKUSC2018]最大前缀和

    [PKUSC2018]最大前缀和 题目大意: 有\(n(n\le20)\)个数\(A_i(|A_i|\le10^9)\).求这\(n\)个数在随机打乱后最大前缀和的期望值与\(n!\)的积在模\(99 ...

  2. BZOJ_5369_[Pkusc2018]最大前缀和_状压DP

    BZOJ_5369_[Pkusc2018]最大前缀和_状压DP Description 小C是一个算法竞赛爱好者,有一天小C遇到了一个非常难的问题:求一个序列的最大子段和. 但是小C并不会做这个题,于 ...

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

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

  4. bzoj 5369 最大前缀和

    Written with StackEdit. Description 小\(C\)是一个算法竞赛爱好者,有一天小\(C\)遇到了一个非常难的问题:求一个序列的最大子段和. 但是小\(C\)并不会做这 ...

  5. 【洛谷5369】[PKUSC2018] 最大前缀和(状压DP)

    点此看题面 大致题意: 对于一个序列,求全排列下最大前缀和之和. 状压\(DP\) 考虑如果单纯按照题目中对于最大前缀和的定义,则一个序列它的最大前缀和是不唯一的. 为了方便统计,我们姑且规定,如果一 ...

  6. [PKUSC2018]最大前缀和(DP)

    题意:求一个序列随机打乱后最大前缀和的期望. 考场上发现不管怎么设状态都写不出来,实际上只要稍微转换一下就好了. 一个前缀[1..k]是最大前缀,当且仅当前面的所有后缀[k-1,k],[k-2,k], ...

  7. BZOJ 4236 "JOIOJI"(前缀和+map+pair)

    传送门: [1]:BZOJ [2]:洛谷 •题解 定义数组 a,b,c 分别表示 'J' , 'O' , 'I' 的前缀和: 要想使区间 (L,R] 满足条件当且仅当 a[R]-a[L] = b[R] ...

  8. LOJ6433 [PKUSC2018] 最大前缀和 【状压DP】

    题目分析: 容易想到若集合$S$为前缀时,$S$外的所有元素的排列的前缀是小于$0$的,DP可以做到,令排列前缀个数小于0的是g[S]. 令f[S]表示$S$是前缀,转移可以通过在前面插入元素完成. ...

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

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

随机推荐

  1. Spring学习(三)——集成 Velocity

    上篇文章http://www.cnblogs.com/wenjingu/p/3822989.html我们使用Gradle构建了一个简单的Spring MVC Web应用程序, 本篇将在上篇的基础上将j ...

  2. jquery-tmpl 插件

    做项目时页面上有处功能是:在页面有处列表.有添加,我添加修改或删除后要刷新这个列表,首先想到的是局部刷新,但我们一般说的局部刷新就是利于ajax去后台调用数据并显示,而这里是一整个列表就比较麻烦了,刷 ...

  3. WordCloud 简介

    WordCloud 简介 GitHub GitHub:https://github.com/amueller/word_cloud example:https://github.com/amuelle ...

  4. day13学python 协程+事件驱动

    协程+事件驱动 协程 (微线程)--用处多,重点 当调度切换时 靠寄存器上下文和栈保存 要使用时再调用(即可不会因io传输数据卡壳 从而耗时无法继续进行)实现并行 优缺点: 优点: 1 无需同线程上下 ...

  5. css3动画(animation)效果3-正方体合成

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. 原生态js回顶部

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. bzoj 4283 魔法少女伊莉雅

    题目大意 给定一个 $n$ 个点 $m$ 条边的带正权无向图.要求找一条路径满足: 它是一条简单路径 它是一条严格次短路 对于任何一条可能存在于最短路上的边,不能包含它的反向边. 不存在这条路径输出 ...

  8. Linux 下安装 resync 介绍

    Linux 下安装 resync 介绍 这是官网,找到对应版本的下载地址. 这里提供Linux_X64的安装包 wget '' https://download-cdn.resilio.com/sta ...

  9. 重置root密码

    一. ubuntu忘记密码解决方法 1. 开机按shift 2. 选择高级选项,进入后选择恢复模式(不要按回车),按e进入编辑模式 3. 修改linux命令中的recovery nomodest 为 ...

  10. java FastJSON的使用

    1.JSON介绍 JSON(javaScript Object Notation)是一种轻量级的数据交换格式.主要采用键值对({"name": "json"}) ...