zoukankan      html  css  js  c++  java
  • 【2019csp模拟】两段子序列

    [2019知临中学csp模拟] 两段子序列

    题目描述

    给定一个长度为n的序列,从中选出两段不相交的连续子序列,子序列的长度不能为 0,使
    得这两段的和最大。

    (mathbb{Solution})

    只选一个这样的连续子序列很简单,一遍扫过去顺便维护即可, 那么两段可以简单得转化为两段一个的拼接。

    所以 pre 数组记为选取一个序列的前缀答案, suf 记为后缀的答案,注意题目要求至少选一个点。

    枚举每个点,合并答案即可。

    代码由于多次修改奇丑无比,我也不知道是怎么过的,只保证正确性/xyx。

    (mathbf{Code:})

    #include <bits/stdc++.h>
    #define Rep(i, a, b) for (int i = (a), bb = (b); i <= bb; ++i)
    #define DOWN(i, a, b) for (int i = (a), bb = (b); i >= bb; --i)
    const int N = 1e5 + 10;
    using namespace std;
    int n, a[N], b[N], cnt = 0;
    inline void read(int &s) {
        s = 0; int w = 1; char c = getchar(); for (; !isdigit(c) && c != '-'; c = getchar());
        if (c == '-') w = -1, c = getchar(); for (; isdigit(c); c = getchar()) s = (s << 3) + (s << 1) + c - 48;
        s *= w;
    }
    int pre[N], suf[N];
    signed main() {
        freopen("two.in", "r", stdin), freopen("two.out", "w", stdout);
        read(n);
        Rep(i, 1, n) { read(a[i]); if ((a[i] >= 0 && b[i] <= 0) || (a[i] <= 0 && b[i] >= 0)) b[++cnt] = a[i]; else b[cnt] += a[i]; }
        int sum = 0;
        Rep(i, 1, n) { sum += b[i]; if (sum < 0) sum = 0; pre[i] = max(pre[i - 1], sum); } sum = 0;
        DOWN(i, n, 1) { sum += b[i]; if (sum < 0) sum = 0; suf[i] = max(suf[i + 1], sum); }
        int maxn = 0; Rep(i, 0, n) { if (b[i] < 0) maxn = max(maxn, pre[i] + suf[i + 1]); }
        if (n == 2) { printf("%d
    ", a[1] + a[2]); return 0;}
        printf("%d
    ", maxn);
        return 0;
    }
    
  • 相关阅读:
    php安装xcache (5.4)
    nginx博客系统(内含nginx图片缩略图处理代码,不错)
    一个mysql开启多个端口
    mysql源码重启
    ecshop支付时减库存方法
    n阶幻方问题
    codeforces 710A King Moves(水)
    关于ios::sync_with_stdio(false);和 cin.tie(0)加速c++输入输出流
    codeforces 701C. They Are Everywhere(尺取法)
    codeforces 701 B. Cells Not Under Attack
  • 原文地址:https://www.cnblogs.com/yywxdgy/p/13518379.html
Copyright © 2011-2022 走看看