每日一题之 hiho1778 最优子段

描述
给定一个长度为 n 的序列 ai 和两个整数 A, B,要求你找一对数l, r,要求1 ≤ l ≤ r 且A×(ai+ai+1+…+ar)+B 最大

输入
第一行三个整数 n, A, B

第二行 n 个整数,第 i 个整数表示 ai

1 ≤ n ≤ 106

-106 ≤ A, B, ai ≤ 106

输出
输出最大的A×(ai+ai+1+…+ar)+B

样例解释
选择 (1,1) 或者 (4,4) 都可以

样例输入
4 2 3
0 -2 -2 0
样例输出
3

思路:

最大子段和得变形,主要考虑到系数A的符号,有两种情况,1. 如果是 + 的话,直接求最大子段和。2. 如果是 的话,就把数组的元素取反,再求最大子段和,最后再对答案取反。

#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

const int maxn = 1e6+5;

long long A[maxn];
long long B[maxn];

int main()
{
    int n,a,b;
    cin >> n >> a >> b;

    for (int i = 0; i < n; ++i)
        cin >> A[i];

    long long ptmp = A[0];
    long long ntmp = -A[0];
    long long pres = 0;
    long long nres = 0;

    for (int i = 1; i < n; ++i) {

        if (ptmp > 0) {
            ptmp += A[i];   
        }
        else {
            ptmp = A[i];
        }

        if (ntmp > 0) {
            ntmp -= A[i];
        }
        else {
            ntmp = -A[i];
        }

        nres = max(nres,ntmp);
        pres = max(pres,ptmp);

    }

    if (a >= 0)
        cout << a*pres+b << endl;
    else 
        cout << -a*nres+b << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/u014046022/article/details/80961326