最大连续和_Aizu-ALDS1_1_D

1 问题描述

​ 给定n个整数(可正可负) a 0 , a 1 , . . . a n − 1 a_0, a_1, ... a_{n-1} a0,a1,...an1,求它们的最大连续和。

2 转换成累加量

S 0 = 0 , S i = ∑ j = 0 i − 1 a j ( 1 ≤ i ≤ n ) S_0 = 0, S_i = \sum_{j=0}^{i-1}{a_j} {(1{\leq}i{\leq}n)} S0=0,Si=j=0i1aj(1in)

​ 可以得到原序列的累加量序列 S 0 , S 1 , . . . S n S_0, S_1, ... S_n S0,S1,...Sn。这样原序列的任意连续和都可以表示为 S j − S i ( 0 ≤ i < j ≤ n ) S_j-S_i (0{\leq}i<j{\leq}n) SjSi(0i<jn),找出最大的 S j − S i S_j-S_i SjSi即可。

3 算法分析

1.O( n 2 n^2 n2)算法

​ 二重循环遍历 i i i j j j,更新最大的 S j − S i S_j-S_i SjSi

2. O(n)算法

​ 对于确定的 j j j S j − S i S_j-S_i SjSi最小等价于 S i ( 0 ≤ i < j ) S_i(0{\leq}i<j) Si(0i<j)。因此,只需要一重循环,遍历 j j j的同时维护目前为止最小的 S i S_i Si,更新最大的 S j − S i S_j-S_i SjSi

4 实例

​ 题目Maximum Profit选自Aizu-ALDS1_1_D,内容如下:

Write a program which reads values of a currency R t R_t Rt at a certain time t t t ( t = 0 , 1 , 2 , . . . n − 1 ) (t=0,1,2,...n−1) (t=0,1,2,...n1), and reports the maximum value of R j − R i R_j−R_i RjRi where j > i j>i j>i .

Input

The first line contains an integer n. In the following n lines, R t R_t Rt ( t = 0 , 1 , 2 , . . . n − 1 ) (t=0,1,2,...n−1) (t=0,1,2,...n1) are given in order.

Output

Print the maximum value in a line.

Constraints

  • 2 ≤ n ≤ 200 , 000 2≤n≤200,000 2n200,000

  • 1 ≤ R t ≤ 1 0 9 1≤R_t≤10^9 1Rt109

Sample Input 1

6
5
3
1
3
4
3

Sample Output 1

3

代码如下:

//https://vjudge.net/problem/Aizu-ALDS1_1_D
#include<iostream>
#include<algorithm>
using namespace std;
const int Min_Num = -2000000000;    //定义足够小的常数,用于取max
int n, ans;

int main(){
    int cur_min = -Min_Num;
    ans = Min_Num;
    cin >> n;
    for(int i = 0; i < n; i++){
        int rt;
        cin >> rt;
        if(i){
            ans = max(ans, rt - cur_min);   //更新结果
        }
        cur_min = min(cur_min, rt);     //维护当前量之前的最小值
    }
    cout << ans << endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值