time limit: 20 sec
memory limit: 512 mb
小c是乙個演算法競賽愛好者,有一天小c遇到了乙個非常難的問題:求乙個序列的最大子段和。
但是小c並不會做這個題,於是小c決定把序列隨機打亂,然後取序列的最大字首和作為答案。
小c是乙個非常有自知之明的人,他知道自己的演算法完全不對,所以並不關心正確率,他只關心求出的解的期望值,
現在請你幫他解決這個問題,由於答案可能非常複雜,所以你只需要輸出答案乘上n!後對998244353取模的值,顯然這是個整數。
注:最大字首和的定義:i∈[1,n],sigma(a
j)的最大值,其中1<=j<=i
第一行乙個正整數nnn,表示序列長度。
第二行n個數,表示原序列a[1..n],第i個數表示a[i]。
1≤n≤20,sigma(|ai|)<=10^9,其中1<=i<=n
輸出乙個非負整數,表示答案。 2
-1 2
3考慮乙個分界點p,使得∑a₁~p為最大字首和,那麼顯然p之後的所有字首和均<0,否則就存在可以替換p的方案使得字首和更大。
用sum[i]表示子集i的數值和,f[i]表示最大字首和為sum[i]的方案數,從後往前插入,>0就可以轉移。g[i]表示任意字首和均為負的方案數,從前往後插入,<0就可以轉移。f[i]和g[i]均可以通過動態規劃求得。最後答案即為sum[s]*f[s]*g[s′]。時間複雜度o(2^n*n)
code:
#include#include#include#include#include#include#define mod 998244353
#define n 21
using namespace std;
int n,a[n],sum[1<< n],f[1<>j)&1)
g[i]=(g[i]+g[i^(1<0)
for(int j=0;j>j)&1))
f[i|(1
}printf("%d\n",ans);
return 0;
}
P5369 PKUSC2018 最大字首和
p5369 題意 求所有排列下的最大字首和之和 一步轉化 求最大字首和的字首由數集s組成的方案數,統計答案時直接乘上sum s 即可 考慮最大字首和的性質 設最大字首和為sum i 到i的字尾均為正數 i後的字首均為負數 令sum i 集合 i 內所有數的和。令f i 集合 i內的數組成的排列,最大...
BZOJ5368 Pkusc2018 真實排名
time limit 10 sec memory limit 256 mb 小c是某知名比賽的組織者,該比賽一共有n名選手參加,每個選手的成績是乙個非負整數,定義乙個選手的排名是 成績不小於他的選手的數量 包括他自己 例如如果333位選手的成績分別是 1,2,2 那麼他們的排名分別是 3,2,2 擁...
BZOJ5368 Pkusc2018 真實排名
time limit 10 sec memory limit 256 mb submit 163 solved 83 小c是某知名比賽的組織者,該比賽一共有n名選手參加,每個選手的成績是乙個非負整數,定義乙個選手的排名是 成績不小於他的選手的數量 包括他自己 例如如果333位選手的成績分別是 1,2...