zoukankan      html  css  js  c++  java
  • Luogu5369 [PKUSC2018]最大前缀和

    题目链接:洛谷

    题目大意:给定一个长为$n$的整数序列,求全排列的最大前缀和(必须包含第一个数)之和。

    数据范围:$1leq nleq 20,1leq sum_{i=1}^n|a_i|leq 10^9$


    神级状压dp,不得不服。。。

    我们考虑对全排列的最大前缀和的前缀的集合进行dp。

    设$f[S],g[S]$分别表示集合$S$内的数组成的排列中,最大前缀和为$sum[S]$和负数的排列数,其中$sum[S]$为$sum_{iin S}i$

    我们发现,如果这个最大的前缀组成的集合就是$S$,当且仅当前$|S|$个数的最大前缀和为$sum[S]$,后面$n-|S|$个数的最大前缀和为负数,所以

    $$ans=sum_{Ssubset U}sum[S]*f[S]*g[U-S]$$

    其中$U$表示全集。注意这里$g[S]$必须要求是负数才可以,0不行,否则可能会重复统计。

    然后考虑对$f,g$进行dp。

    若$sum[S]geq 0$,则$g[S]=0$,否则枚举最后一个数$j$,即$g[S]=sum_{jin S}g[S-{j}]$

    若$sum[S]geq 0$,则对于$j otin S$,$f[S+{j}]+=f[S]$,否则$f[S]$对$f[S+{j}]$无贡献。

    时间复杂度$O(n2^n)$,空间复杂度$O(2^n)$

     1 #include<bits/stdc++.h>
     2 #define Rint register int 
     3 using namespace std;
     4 typedef long long LL;
     5 const int N = 1 << 20, mod = 998244353;
     6 int n, lim, sum[N], f[N], g[N], ans;
     7 inline int add(int a, int b){int c = a + b; return c >= mod ? (c - mod) : c;}
     8 int main(){
     9     scanf("%d", &n); lim = 1 << n; g[0] = 1;
    10     for(Rint i = 0;i < n;i ++){
    11         scanf("%d", sum + (1 << i));
    12         f[1 << i] = 1;
    13     }
    14     for(Rint i = 1;i < lim;i ++)
    15         sum[i] = add(sum[i ^ (i & -i)], sum[i & -i]);
    16     for(Rint i = 1;i < lim;i ++)
    17         if(sum[i] >= 0){
    18             for(Rint j = 0;j < n;j ++)
    19                 if(!(i & (1 << j))) f[i | (1 << j)] = add(f[i | (1 << j)], f[i]);
    20         } else {
    21             for(Rint j = 0;j < n;j ++)
    22                 if(i & (1 << j)) g[i] = add(g[i], g[i ^ (1 << j)]);
    23         }
    24     for(Rint i = 1;i < lim;i ++)
    25         ans = add(ans, (LL) sum[i] * f[i] % mod * g[lim - 1 - i] % mod) % mod;
    26     printf("%d", (ans % mod + mod) % mod);
    27 }
    Luogu5369
  • 相关阅读:
    python实现单链表及常用方法->判空|长度|头尾及指定插入|删除|搜索|反转
    k8s v1.21.9集群安装带认证的elk 6.8.18
    docker安装Elasticsearch6.8集群并设置密码
    kubernetes v1.20.9部署keepalived-vip实现高可用pod访问
    rsync远程同步工具的使用-实现跳板机与内网数据传输
    旧金山大学 大卫 算法演示
    IO多路复用之select、poll、epoll详解-转载
    docker容器中使用systemctl命令 set-hostname
    win7 安装ss
    常用相似度语料
  • 原文地址:https://www.cnblogs.com/AThousandMoons/p/10901593.html
Copyright © 2011-2022 走看看