1 问题描述
给定n个整数(可正可负) a 0 , a 1 , . . . a n − 1 a_0, a_1, ... a_{n-1} a0,a1,...an−1,求它们的最大连续和。
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=0∑i−1aj(1≤i≤n)
可以得到原序列的累加量序列 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) Sj−Si(0≤i<j≤n),找出最大的 S j − S i S_j-S_i Sj−Si即可。
3 算法分析
1.O( n 2 n^2 n2)算法
二重循环遍历 i i i 和 j j j,更新最大的 S j − S i S_j-S_i Sj−Si。
2. O(n)算法
对于确定的 j j j, S j − S i S_j-S_i Sj−Si最小等价于 S i ( 0 ≤ i < j ) S_i(0{\leq}i<j) Si(0≤i<j)。因此,只需要一重循环,遍历 j j j的同时维护目前为止最小的 S i S_i Si值,更新最大的 S j − S i S_j-S_i Sj−Si。
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,...n−1), and reports the maximum value of R j − R i R_j−R_i Rj−Ri 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,...n−1) are given in order.
Output
Print the maximum value in a line.
Constraints
2 ≤ n ≤ 200 , 000 2≤n≤200,000 2≤n≤200,000
1 ≤ R t ≤ 1 0 9 1≤R_t≤10^9 1≤Rt≤109
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;
}