[PKUSC2018]最大前缀和(DP)】的更多相关文章

传送门 思路 这么一道签到题竟然没切掉真是丢人呢-- 首先有一个\(O(3^n)\)的SB方法,记录\(dp_{S,T}\)表示已经填进去了\(S\),当前最大前缀和集合为\(T\),随便转移.太简单了就不细讲了. 挖掘一下题目的性质:一个序列必然可以被分成两部分:前面的前缀和&后面的部分. 后面的部分满足一个性质:任意前缀和都<0,所以很容易DP. 前面可以考虑每次往数列前面加数,那么就必须要满足原来的数列总和\(\ge 0\),也很容易DP,具体可以见代码. 然后就做完了--我这都不会真…
题意:求一个序列随机打乱后最大前缀和的期望. 考场上发现不管怎么设状态都写不出来,实际上只要稍微转换一下就好了. 一个前缀[1..k]是最大前缀,当且仅当前面的所有后缀[k-1,k],[k-2,k],...,[1,k]都大于0,后面的所有前缀[k+1,k+2],[k+1,k+3],...,[k+1,n]全部不大于0. 于是设f[S]表示S集合满足所有后缀大于0的排列数,g[S]表示S前缀不大于0的排列数,直接转移,最后答案就是所有集合(空集除外)的f乘上补集的g. 不卡时BZOJ时间榜与码长榜…
BZOJ_5369_[Pkusc2018]最大前缀和_状压DP Description 小C是一个算法竞赛爱好者,有一天小C遇到了一个非常难的问题:求一个序列的最大子段和. 但是小C并不会做这个题,于是小C决定把序列随机打乱,然后取序列的最大前缀和作为答案. 小C是一个非常有自知之明的人,他知道自己的算法完全不对,所以并不关心正确率,他只关心求出的解的期望值, 现在请你帮他解决这个问题,由于答案可能非常复杂,所以你只需要输出答案乘上n!后对998244353取模的值,显然这是个整数. 注:最大前…
题目链接: [PKUSC2018]最大前缀和 设$f[S]$表示二进制状态为$S$的序列,任意前缀和都小于等于$0$的方案数. 设$g[S]$表示二进制状态为$S$的序列是整个序列的最大前缀和的方案数. 设$sum[S]$表示二进制状态为$S$的序列的每个数的和. 那么答案就是$\sum\limits_{S=1}^{2^n-1}sum[S]*g[S]*f[(2^n-1)-S]$. 对于$f[S]$,转移相当于在序列前面加一个数,只有当前集合中数的和小于等于$0$时可以转移. 对于$g[S]$,只…
[PKUSC2018]最大前缀和 题目大意: 有\(n(n\le20)\)个数\(A_i(|A_i|\le10^9)\).求这\(n\)个数在随机打乱后最大前缀和的期望值与\(n!\)的积在模\(998244353\)意义下的值.其中最大前缀和的定义为\(\forall i\in[1,n]\sum_{j=1}^iA_j\)的最大值. 思路: 考虑一个分界点\(p\),使得\(\sum A_{1\sim p}\)为最大前缀和,那么显然\(p\)之后的所有前缀和均\(<0\),否则就存在可以替换\(…
题目分析: 容易想到若集合$S$为前缀时,$S$外的所有元素的排列的前缀是小于$0$的,DP可以做到,令排列前缀个数小于0的是g[S]. 令f[S]表示$S$是前缀,转移可以通过在前面插入元素完成. 代码: #include<bits/stdc++.h> using namespace std; ; ; int n; int a[maxn]; <<],g[<<],sum[<<],arr[<<]; void read(){ scanf("…
点此看题面 大致题意: 对于一个序列,求全排列下最大前缀和之和. 状压\(DP\) 考虑如果单纯按照题目中对于最大前缀和的定义,则一个序列它的最大前缀和是不唯一的. 为了方便统计,我们姑且规定,如果一个序列中存在多个最大前缀和,我们取最靠后的一个. 由此我们想到,对于一个序列可以把它分为两部分\([1,k]\)和\([k+1,n]\)满足: \([1,k]\)是\([1,k]\)本身的最大前缀和. \([k+1,n]\)内所有前缀和均小于\(0\). 显然,由于\([1,k]\)是其本身的最大前…
题目大意:求给定的 $n$ 个数的所有排列的最大前缀和(不能为空)之和对 $10^9+7$ 取模的值. $1\le n\le 20,1\le\sum|a_i|\le 10^9$. 神级DP.杂题选讲的神级毒瘤讲题人CDW讲的. 考虑一个集合 $S$ 能作为最大前缀和出现的方案数.(即贡献系数) 发现前 $|S|$ 个数满足最大前缀和是整个序列,后 $n-|S|$ 个数满足最大前缀和 $<0$.(虽然 $\le 0$ 也行,但为了避免重复统计就要 $<0$) 设 $f[S]$ 为在 $S$ 的所…
Description 小C是一个算法竞赛爱好者,有一天小C遇到了一个非常难的问题:求一个序列的最大子段和. 但是小C并不会做这个题,于是小C决定把序列随机打乱,然后取序列的最大前缀和作为答案. 小C是一个非常有自知之明的人,他知道自己的算法完全不对,所以并不关心正确率,他只关心求出的解的期望值, 现在请你帮他解决这个问题,由于答案可能非常复杂,所以你只需要输出答案乘上n!后对998244353取模的值,显然这是个整数. 注:最大前缀和的定义:i∈[1,n],Sigma(aj)的最大值,其中1<…
分析 我们让每个数列在第一个取到最大前缀和的位置被统计到. 假设一个数列在\(pos\)处第一次取到最大前缀和,分析性质,有: 下标在\([1,pos]\)之间的数形成的数列的每个后缀和(不包括整个数列,因为要求非空)都大于\(0\). 下标在\([pos+1,n]\)之间的数形成的数列的每个前缀和(包括整个数列)都小于等于\(0\). 正确性显然. 所以我们可以把数列从\(pos\)分成两部分,分别算出各自的方案数再相乘. \([1,pos]\)部分 令\(f[S]\)表示\(S\)中的数形成…