状态压缩

P5369

题意:求所有排列下的最大前缀和之和

一步转化: 求最大前缀和的前缀由数集S组成的方案数, 统计答案时直接乘上sum(S)即可

考虑最大前缀和的性质:

设最大前缀和为sum[i]

  1. 到i的后缀均为正数
  2. i后的前缀均为负数

令sum[i] = 集合 i 内所有数的和。

令f[i] = 集合 i内的数组成的排列,最大前缀和 = sum[i]的方案数。

令g[i] = 集合 i内的数组成的排列,所有的最大前缀和都 < 0 的方案数。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 25;
const int P = 998244353;
int n, a[N];
int f[1050050], g[1050050];
int sum[1050050];
inline int to(int x) {
return 1 << x;
}
int main() {
cin >> n; int all = to(n) - 1;
for (int i = 1;i <= n; i++)
cin >> a[i], f[to(i-1)] = 1, sum[to(i-1)] = a[i];
for (int i = 1;i <= all; i++)
sum[i] = sum[(i & -i)] + sum[i ^ (i & -i)];
g[0] = 1;
for (int i = 0;i < all; i++) {
if (sum[i] >= 0) {
for (int j = 1;j <= n; j++)
if (!(i & to(j-1)))
f[i | to(j-1)] = ((long long)f[i] + f[i | to(j-1)]) % P;
}
else {
for (int j = 1;j <= n; j++)
if (i & (to(j-1)))
g[i] = ((long long)g[i] + g[i ^ to(j-1)]) % P;
}
}
long long ans = 0;
for (int i = 1;i <= all; i++)
ans = (ans + (long long)f[i] * g[all^i] % P * sum[i] % P) % P;
cout << (ans % P + P) % P << endl;
return 0;
}

P5369 [PKUSC2018]最大前缀和的更多相关文章

  1. 洛谷P5369 [PKUSC2018]最大前缀和 [DP]

    传送门 思路 这么一道签到题竟然没切掉真是丢人呢-- 首先有一个\(O(3^n)\)的SB方法,记录\(dp_{S,T}\)表示已经填进去了\(S\),当前最大前缀和集合为\(T\),随便转移.太简单 ...

  2. [PKUSC2018]最大前缀和

    [PKUSC2018]最大前缀和 题目大意: 有\(n(n\le20)\)个数\(A_i(|A_i|\le10^9)\).求这\(n\)个数在随机打乱后最大前缀和的期望值与\(n!\)的积在模\(99 ...

  3. BZOJ_5369_[Pkusc2018]最大前缀和_状压DP

    BZOJ_5369_[Pkusc2018]最大前缀和_状压DP Description 小C是一个算法竞赛爱好者,有一天小C遇到了一个非常难的问题:求一个序列的最大子段和. 但是小C并不会做这个题,于 ...

  4. [PKUSC2018]最大前缀和——状压DP

    题目链接: [PKUSC2018]最大前缀和 设$f[S]$表示二进制状态为$S$的序列,任意前缀和都小于等于$0$的方案数. 设$g[S]$表示二进制状态为$S$的序列是整个序列的最大前缀和的方案数 ...

  5. LOJ6433 [PKUSC2018] 最大前缀和 【状压DP】

    题目分析: 容易想到若集合$S$为前缀时,$S$外的所有元素的排列的前缀是小于$0$的,DP可以做到,令排列前缀个数小于0的是g[S]. 令f[S]表示$S$是前缀,转移可以通过在前面插入元素完成. ...

  6. BZOJ5369:[PKUSC2018]最大前缀和(状压DP)

    Description 小C是一个算法竞赛爱好者,有一天小C遇到了一个非常难的问题:求一个序列的最大子段和. 但是小C并不会做这个题,于是小C决定把序列随机打乱,然后取序列的最大前缀和作为答案. 小C ...

  7. BZOJ5369 [Pkusc2018]最大前缀和

    题意 小C是一个算法竞赛爱好者,有一天小C遇到了一个非常难的问题:求一个序列的最大子段和. 但是小C并不会做这个题,于是小C决定把序列随机打乱,然后取序列的最大前缀和作为答案. 小C是一个非常有自知之 ...

  8. bzoj 5369: [Pkusc2018]最大前缀和

    Description 小C是一个算法竞赛爱好者,有一天小C遇到了一个非常难的问题:求一个序列的最大子段和. 但是小C并不会做这个题,于是小C决定把序列随机打乱,然后取序列的最大前缀和作为答案. 小C ...

  9. [PKUSC2018]最大前缀和(DP)

    题意:求一个序列随机打乱后最大前缀和的期望. 考场上发现不管怎么设状态都写不出来,实际上只要稍微转换一下就好了. 一个前缀[1..k]是最大前缀,当且仅当前面的所有后缀[k-1,k],[k-2,k], ...

随机推荐

  1. Java NIO 上

    概述: NIO主要有三大核心部分:Channel(通道),Buffer(缓冲区), Selector. 传统IO基于字节流和字符流进行操作,而NIO基于Channel和Buffer(缓冲区)进行操作, ...

  2. TK可视化之文件内容查找(升级篇)

    升级为带有选择框 分三种查看格式一种是表格查看 一种是文本查看 一种是列表 1.列表查看类 # listbox 显示数据 import tkinter class ListShowData: def ...

  3. [python]打开文件操作open用法

    1. 格式 handle = open(file_name, access_mode = 'r') file_name: 希望打开的文件名 access_mode: 'r'表示读取,'w'表示写入,' ...

  4. CF1028D Order book 思维

    Order book time limit per test 2 seconds memory limit per test 256 megabytes input standard input ou ...

  5. HDU 4565 So Easy! 广义斐波拉数 数论 (a+sqrt(b))^n%mod 模板

    So Easy! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  6. Java中时间API使用详解

    目录 Java中时间API使用详解 1. 时区概念 2. 几种常见的时间 3. 时间戳 4. Java中的时间API 5. Java8中新添加的时间API 6. 在东八区的机器上获得美国时间 Java ...

  7. 英文写作report

    Writting Attached Files   Maybe you might want to get familiar about how to write the Final report. ...

  8. QRowTable表格控件(五)-重写表头排序、支持第三次单击恢复默认排序

    目录 一.原生表格 二.效果展示 三.实现方式 1.排序列定制 2.排序交互修改 四.相关文章 原文链接:QRowTable表格控件(五)-重写表头排序.支持第三次单击恢复默认排序 一.原生表格 开发 ...

  9. Unity3D_07_日志、文本打印

    1.Debug.Log(“hello”); 2.打开控制台查看日志:ctrl+shift+c 3.输出一个位置的坐标(需要转换成字符串.ToString()) Vector3 worldPositio ...

  10. 解决python -m pip install --upgrade pip 升级不成功问题

    1.使用命令出现. You are , however version is available. You should consider upgrading via the 'python -m p ...