[LOJ 6433] [PKUSC 2018] maximum prefix and

[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;
}

Guess you like

Origin www.cnblogs.com/rvalue/p/10934984.html