【PKUSC2018】【loj6433】最大前缀和 状压dp
这题吼啊...
然而还是想了$2h$,写了$1h$。
我们发现一个性质:若一个序列$p$能作为前缀和,那么在序列$p$中,包含序列$p$最后一个数的所有子序列必然都是非负的。
那么,我们
令$f[i]$表示状态$i$中所有数字全部作为前缀和的方案数。
令$g[i]$表示状态$i$中所有数字所组合成的任意排列中,前缀和永远为负数的方案数。
令$s[i]$表示状态$i$中所有数字之和。
ps:若i的第j个二进制位为$1$,则表示状态$i$中,选择了数字$a_j$。($a$序列的下表为$0$到$n-1$)
通过冷静分析,不难得出:
$s[i]$很好求
$f[i]=\sum_{(2^j\ and\ i)=2^j∩s[i-2^j]+a[j]≥0} f[i-2^j]$
$g[i]=\sum_{(2^j\ and\ i)=2^j∩s[i-2^j]+a[j]<0} g[i-2^j]$
显然$f[0]=g[0]=1$。
统计答案时,分前缀和$≥0$,前缀和$<0$两类讨论。
当前缀和$≥0$时
$ans1=\sum_{i=1}^{2^n-1} s[i] \times f[i] \times g[2^n-1-i] $
当前缀和<0时
$ans2=\sum_{j=0}^{n=1} \sum_{i=0} (a[j]+s[i])\times f[i]\times g[2^n-1-i-2^j]\ \ \ [(2^j\ and\ i=0)∩s[i]<0∩s[i]>-a[j]]$
最终所求答案即$ans1+ans2$。
然后就完结了。
时间复杂度为$O(n \times 2^n)$。
#include<bits/stdc++.h>
#define M 20
#define L long long
#define MOD 998244353
using namespace std; L f[<<M]={},g[<<M]={},a[M]={},he[<<M]={}; int main(){
int n,m; scanf("%d",&n); m=<<n;
for(int i=;i<n;i++) cin>>a[i];
for(int i=;i<m;i++)
for(int j=;j<n;j++)
if(i&(<<j)) he[i]+=a[j];
f[]=;
for(int i=;i<m;i++){
for(int j=;j<n;j++)
if((i&(<<j))&&he[i^(<<j)]+a[j]>=){
f[i]=(f[i]+f[i^(<<j)])%MOD;
}
}
for(int i=;i<n;i++) a[i]=-a[i];
for(int i=;i<m;i++) he[i]=-he[i];
g[]=;
for(int i=;i<m;i++){
for(int j=;j<n;j++)
if((i&(<<j))&&he[i^(<<j)]+a[j]>){
g[i]=(g[i]+g[i^(<<j)])%MOD;
}
}
for(int i=;i<n;i++) a[i]=-a[i];
for(int i=;i<m;i++) he[i]=-he[i];
L ans=;
for(int j=;j<n;j++) if(a[j]<){
//f[1<<j]=1;
for(int i=;i<m;i++)
if((i&(<<j))==){
if(he[i]<||he[i]>-a[j]) continue;
int hh=(m-)^i^(<<j);
ans=(ans+(a[j]+he[i])*f[i]%MOD*g[hh]%MOD+MOD)%MOD;
}
}
for(int i=;i<m;i++)
ans=(ans+f[i]*he[i]%MOD*g[(m-)^i]%MOD+MOD)%MOD;
cout<<ans<<endl;
}
【PKUSC2018】【loj6433】最大前缀和 状压dp的更多相关文章
- LOJ#6433. 「PKUSC2018」最大前缀和 状压dp
原文链接https://www.cnblogs.com/zhouzhendong/p/LOJ6433.html 题解 枚举一个集合 S ,表示最大前缀和中包含的元素集为 S ,然后求出有多少个排列是这 ...
- LOJ 6433 「PKUSC2018」最大前缀和——状压DP
题目:https://loj.ac/problem/6433 想到一个方案中没有被选的后缀满足 “该后缀的任一前缀和 <=0 ”. 于是令 dp[ S ] 表示选了点集 S ,满足任一前缀和 & ...
- [PKUSC2018]最大前缀和——状压DP
题目链接: [PKUSC2018]最大前缀和 设$f[S]$表示二进制状态为$S$的序列,任意前缀和都小于等于$0$的方案数. 设$g[S]$表示二进制状态为$S$的序列是整个序列的最大前缀和的方案数 ...
- BZOJ5369:[PKUSC2018]最大前缀和(状压DP)
Description 小C是一个算法竞赛爱好者,有一天小C遇到了一个非常难的问题:求一个序列的最大子段和. 但是小C并不会做这个题,于是小C决定把序列随机打乱,然后取序列的最大前缀和作为答案. 小C ...
- BZOJ_5369_[Pkusc2018]最大前缀和_状压DP
BZOJ_5369_[Pkusc2018]最大前缀和_状压DP Description 小C是一个算法竞赛爱好者,有一天小C遇到了一个非常难的问题:求一个序列的最大子段和. 但是小C并不会做这个题,于 ...
- 「PKUSC2018」最大前缀和(状压dp)
前言 考试被\(hyj\)吊着打... Solution 考虑一下如果前缀和如果在某一个位置的后面的任意一个前缀和都<=0,肯定这就是最大的. 然后这样子就考虑左右两边的状压dp,然后就好了. ...
- Loj 6433. 「PKUSC2018」最大前缀和 (状压dp)
题面 Loj 题解 感觉挺难的啊- 状压\(dp\) 首先,有一个性质 对于一个序列的最大前缀和\(\sum_{i=1}^{p} A[i]\) 显然对于每个\(\sum_{i=p+1}^{x}A[i] ...
- 【洛谷5369】[PKUSC2018] 最大前缀和(状压DP)
点此看题面 大致题意: 对于一个序列,求全排列下最大前缀和之和. 状压\(DP\) 考虑如果单纯按照题目中对于最大前缀和的定义,则一个序列它的最大前缀和是不唯一的. 为了方便统计,我们姑且规定,如果一 ...
- T2988 删除数字【状压Dp+前缀和优化】
Online Judge:从Topcoder搬过来,具体哪一题不清楚 Label:状压Dp+前缀和优化 题目描述 给定两个数A和N,形成一个长度为N+1的序列,(A,A+1,A+2,...,A+N-1 ...
随机推荐
- FTP中各文件目录的说明
DirectAdmin:FTP中各文件目录的说明 当您使用FTP连上空间后,FTP列表会出现以下文件和目录: domains目录:网站文件存放目录:public_html目录:快捷目录,可以快 ...
- Myeclipse如何更新maven
选中项目-->右键-->Maven4MyEclipse-->Update Project-->勾选Force update of.....就ok了
- spring mvc 用cookie和拦截器实现自动登录(/免登录)
Cookie/Session机制详解:http://blog.csdn.net/fangaoxin/article/details/6952954 SpringMVC记住密码功能:http://blo ...
- 2018.09.02 bzoj1003: [ZJOI2006]物流运输(dp+最短路转移)
传送门 dp好题. 每一天要变更路线一定还是走最短路. 所以l~r天不变更路线的最优方案就是把l~r天所有不能走的点都删掉再求最短路.显然是可以dp的. 设f[i]表示第i天的最优花销.那么我们枚举在 ...
- IntelliJ IDEA 2017版 加载springloaded-1.2.4.RELEASE.jar实现热部署
1.配置pom.xml文档(详见:http://www.cnblogs.com/liuyangfirst/p/8318664.html) <?xml version="1.0" ...
- strcpy,strlen, strcat, strcmp函数,strlen函数和sizeof的区别
//计算字符串实际长度 //strlen()函数:当遇到'\0'时,计算结束,'\0'不计入长度之内,如果你只定义没有给它赋初值,这个结果是不定的,它会从首地址一直找下去,直到遇到'\0 ...
- 团队作业(HCL队)第三周—需求改进和系统分析
2.需求&原型改进: 1.问题:游戏中坦克的移动和攻击怎么控制的? 改进: 在游戏中,我控制我方坦克,按下方向键坦克便向按下的方向移动,按下Z键,我方坦克发射炮弹.敌方坦克面向随机的方向移动, ...
- [leetcode] 16. Add Binary
这个题目相对有点奇怪,题目如下: Given two binary strings, return their sum (also a binary string). For example, a = ...
- Java返回当前对象的好处
自己使用了一个第三方框架,发现非常的灵活,于是去研究了下,才知道是返回当前对象,才可以做到,例如以下案例: // 可以不断的点出很多函数 Glide.with(PhotoPagerSlitherAct ...
- Python学习-16.Python中的错误处理
虽然叫错误,但跟 C# 中的异常是一回事.只不过 Python 中叫错误(Error)而 C# 中叫异常(Exception). 先手工产生一个异常: file = open('','r') 上面一句 ...