#include <cstdio>
#include <iostream>
#include <vector>
#include <cmath>
#include <ctime>
using namespace std;
/*
产生长度为length的,元素为[-range,range)中随机数的vector
*/
vector<int> randomVector(int range, int length) {
srand(time(0));
vector<int> v(length);
for (int i = 0; i < length; i++)
v[i] = rand() % (range * 2) - range;
return v;
}
/*
暴力破解 O(n^3)
Sum(i,j) = Sum of seq[i,j]
对于每个i,j, 0 <= i <= j < seq.size()
mcss = max(mcss,Sum(i,j))
*/
int MCSS1(vector<int> seq) {
int mcss = seq[0];
int tot = 0;
for (int i = 0; i < seq.size(); i++) {
for (int j = i; j < seq.size(); j++) {
int sum = 0;
for (int k = i; k <= j; k++) { sum += seq[k]; tot++; }
mcss = max(mcss, sum);
}
}
cout << "MCSS1,inner loop cnt: " << tot << endl;
return mcss;
}
/*
O(n^2)算法
暴力破解算法有很大的时间上的浪费
考虑已经求出Sum(i,j)的情况下再求Sum(i,j+1)可以直接利用之前的Sum(i,j)的结果加上seq[j+1],而不用重新计算
设S(i) = Sum(0,i),则Sum(i,j) = S(j) - S(i-1)
这里就是利用了这一特性,记录序列中每个i( 0 <= i < seq.size )的前i项和,去掉内层循环
*/
int MCSS2(vector<int> seq) {
int tot = 0;
vector<int> S = { 0 };
for (int i = 0; i < seq.size(); i++) { S.push_back(seq[i] + S[i]); tot++; }
int mcss = seq[0];
for (int i = 1; i < S.size(); i++)
for (int j = i; j < S.size(); j++) {
tot++;
mcss = max(mcss, S[j] - S[i - 1]);
}
cout << "MCSS2,inner loop cnt: " << tot << endl;
return mcss;
}
/*
O(nlogn)算法
MCSS3(seq,l,r) 返回在seq[l,r)中的最大连续子序列和,那么MCSS3(seq,0,seq.size)为最终答案
设m为区间中间那个数,seq1为贯穿这个区间的最大连续子序列。
mcss = max(MCSS3(seq,l,m),MCSS3(seq,m,r),seq1)
*/
int MCSS3(vector<int> seq,int l,int r) {
if (r - l == 1) return seq[l];
int m = (l + r) / 2;
int lMax = seq[m - 1], lSum = 0;
for (int i = m - 1; i >= l; i--) {
lSum += seq[i];
lMax = max(lMax, lSum);
}
int rMax = seq[m], rSum = 0;
for (int i = m; i < r; i++) {
rSum += seq[i];
rMax = max(rMax, rSum);
}
return max(max(MCSS3(seq, l, m), MCSS3(seq, m, r)), lMax + rMax);
}
/*
O(n)算法 动态规划
对于seq[i],它可以选择加入前面的连续子序列,也可以选择另开一个子序列。
当前面的连续子序列为负数时,选择另开一个子序列比较好,得到一个包含seq[i]的局部最大连续子序列
当前面的连续子序列为正数时,加入前面的子序列比较好,同样得到一个包含seq[i]的局部最大连续子序列
局部最大子序列中最大的那个即为答案。
*/
int MCSS4(vector<int> seq) {
int mcss = seq[0],sum = seq[0];
for (int i = 1; i < seq.size(); i++) {
// 如果 sum是负数,选择另外开启一个新的序列,因为前面的sum对它无帮助
if (sum < 0) { sum = 0; }
sum += seq[i];
// sum = max(sum+seq[i],seq[i]);
mcss = max(sum, mcss);
}
return mcss;
}
int main() {
vector<int> a = randomVector(1023, 100);// MCSS = 198
cout << "MCSS1: " << MCSS1(a) << endl;
cout << "MCSS2: " << MCSS2(a) << endl;
cout << "MCSS3: " << MCSS3(a, 0, a.size()) << endl;
cout << "MCSS4: " << MCSS4(a) << endl;
return 0;
}