[LOJ 6433] [PKUSC 2018] maximum prefix and
The meaning of problems
Given a length \ (n-\) sequence, and seeking the maximum prefix after this random sequence is multiplied by a desired upset \ (n-! \) After \ (998,244,353 \) values taken film.
Prefix and can not be empty.
\ (n \ 20 \) .
answer
First, this expectation is clearly teasing you ... just count it
We then split into a sequence of two parts, and not greater than the sum of the prefix, the prefix portion and not greater than \ (0 \) . So far the largest prefix of such a sequence and is the first portion and we know just how many such sequences just fine.
Behind the practice feeling a bit mean
We are using two DP solving a subset of the number of program sequences composed of two parts. If the current set is greater than \ (0 \) then obviously not be used to form the second portion, but may be generated in this set we legitimate adding a first portion of the front to form a new value of the first portion. If the current set is not greater than \ (0 \) , then it can only be used for constituting the second portion, and if we can conclude that this set Imperial a a value placed at the end, as long as the remaining value can constitute a legitimate second part, the new sequence can constitute a legitimate second part.
Last enumerated those values in the first part, the second part of the remaining value throw, roll up on it.
Reference Code
#include <bits/stdc++.h>
const int MAXN=21;
const int MOD=998244353;
const int MAXL=(1<<20)|3;
int n;
int a[MAXN];
int dp1[MAXL];
int dp2[MAXL];
int sum[MAXL];
inline int LowBit(int);
int main(){
scanf("%d",&n);
dp2[0]=1;
for(int i=0;i<n;i++){
scanf("%d",a+i);
dp1[1<<i]=1;
sum[1<<i]=a[i];
}
for(int s=1;s<(1<<n);s++){
if(s!=LowBit(s))
sum[s]=sum[s^LowBit(s)]+sum[LowBit(s)];
if(sum[s]>0){
for(int i=0;i<n;i++)
if((s&(1<<i))==0)
(dp1[s^(1<<i)]+=dp1[s])%=MOD;
}
else{
for(int i=0;i<n;i++)
if((s&(1<<i))!=0)
(dp2[s]+=dp2[s^(1<<i)])%=MOD;
}
}
int ans=0;
for(int s=1;s<(1<<n);s++)
(ans+=1ll*sum[s]*dp1[s]%MOD*dp2[((1<<n)-1)^s]%MOD)%=MOD;
printf("%d\n",ans<0?ans+MOD:ans);
return 0;
}
inline int LowBit(int x){
return x&-x;
}