zoukankan      html  css  js  c++  java
  • LOJ#6433. 「PKUSC2018」最大前缀和 状压DP

    思路比较自然.  

    开始的时候有一个地方糊涂了,后来想清楚就好了.   

    这里注意一个地方:  

    令 $f[S]$ 表示 $S$ 集合的所有排列中 sum(S) 为最大值的排列数.    

    然后转移 $f[S]$ 的时候要把新的元素放到序列开头,因为放到结尾的话前面的前缀可能非常小,导致到达不了结尾. 

    code: 

    #include <bits/stdc++.h>  
    #define N 23  
    #define ll long long    
    #define mod 998244353   
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std;    
    int sum[1<<N],f[1<<N],g[1<<N],ge[1<<N],cn[N],a[N],n; 
    inline int lowbit(int x) { return x&(-x); }       
    int main() 
    { 
        // setIO("input"); 
        for(int i=1;i<N;++i) cn[i]=1<<(i-1),ge[cn[i]]=i;               
        scanf("%d",&n); 
        for(int i=1;i<=n;++i) scanf("%d",&a[i]);    
        g[0]=f[0]=1;    
        for(int S=1;S<cn[n+1];++S) 
            sum[S]=sum[S-lowbit(S)]+a[ge[lowbit(S)]];          
        for(int S=1;S<cn[n+1];++S) 
        { 
            int flag=0; 
            for(int j=1;j<=n;++j) 
            {
                if(S&cn[j]) 
                {   
                    if(sum[S]<0)  (g[S]+=g[S^cn[j]])%=mod;   
                    if(sum[S^cn[j]]>=0)                  
                        (f[S]+=f[S^cn[j]])%=mod,flag=-1000;   
                    ++flag; 
                }                      
            } 
            if(flag==1) f[S]=1;  
        }         
        int ans=0; 
        int tot=cn[n+1]-1;       
        for(int S=1;S<cn[n+1];++S) 
        { 
            (ans+=(ll)((ll)f[S]*sum[S]%mod*g[tot-S]%mod+mod)%mod)%=mod; 
        }
        printf("%d
    ",ans); 
        return 0; 
    }
    

      

  • 相关阅读:
    三层架构(我了解并详细分析)
    define a class for a linked list and write a method to delete the nth node.
    无阻塞情况connect生产EINPROGRESS错
    辛星和你解读PHP递归
    Android -- Looper.prepare()和Looper.loop() —深度版
    Canvas翻转方法
    BP神经网络的基本原理
    muduo网络图书馆评测
    HBASE
    MySQL
  • 原文地址:https://www.cnblogs.com/guangheli/p/12974072.html
Copyright © 2011-2022 走看看