感觉比赛中经常能遇到求取一个数组的所有连续子序列中和最大的一个子序列
eg:acw3652,CF 936 B等等
当题目的条件太多时,或是其他知识点掺着许多,第一时间总想到的是BF求取,先求前缀和,再进行循环搜索
const int N=1e5+10;
int array[N];//从1开始存入
int array2[N];
BF:
int max_sum=0;
for(int i=1; i<=n; i++)
array2[i]=array2[i]+array[i-1];
for(int i=1; i<=n; i++){
for(int j=i; j<=n;j++){
max_sum=max(max_sum,array2[j]-array2[i-1]);
}
}
但是BF显然是行不通的 O(nlogn)对于大部分题目的测试数据范围还是太奢侈
这里需要优化
贪心:
int sum=0;//若是最大和可能为0,改为-1e9即可
for(int i=1; i<=n; i++){
if(array[i-1]>0) array[i]+=array[i-1];
//累加的思想,让数组的一部分进行相加
//如果array[i]的前一个序列是大于0的,那么它就会对当前序列有增益效果
//但如果小于<0,加上前面的数会使当前序列变小,舍弃,那么此时的array[i]还是
//原来的数,不会对以后的序列造成影响
//对于等于==0,看题目的要求,是否有约束子序列长度,或是寻找下标等
sum=max(sum,array[i]);
//这时候sum就需要与当前的序列作比较
}
三行代码,简单精炼,个人感觉在比赛中作为题目中需要迅速过掉的过程还是很实用的
for(int i=1; i<=n; i++){
if(a[i]>0) a[i]+=a[i-1];
sum=max(sum,a[i]);
}