1. 暴力法求解,复杂度 n2
#include<bits/stdc++.h>
using namespace std;
const int maxn=1007;
int A[maxn];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>A[i];
}
int max_i,max_j; //记录最大子数组区间
int sum=0,max_sum=0;
for(int i=1;i<=n;i++){
sum=A[i];
for(int j=i+1;j<=n;j++){
sum+=A[j];
if(sum>max_sum){
max_sum=sum;
max_i=i;
max_j=j;
}
}
}
cout<<max_sum<<" "<<max_i<<" "<<max_j<<endl;
//cout<<find_maximum_subarry(A,1,n);
return 0;
}
2.利用分治法求解,nlogn
#include<bits/stdc++.h>
using namespace std;
const int maxn=1007;
int A[maxn];
const int _inf=0xc0c0c0c0; //负无穷
/*
利用分治法求最大连续子数组问题
子数组的位置上一定位于: ①A[low,mid],②A[mid+1,high],③A[low,high](跨越了中点);
分解:
解决:
合并:将第三种子问题划分为合并
*/
//第三种情况,一定是左子数组最大值加上右子数组最大值,且经过中点
int find_max_corssing_subbary(int *A,int low,int mid,int high){
int left_sum=_inf;
int right_sum=_inf;
int sum=0;
//求左子数组最大值
for(int i=mid;i>=low;i--){
sum+=A[i];
if(sum>left_sum){
left_sum=sum;
}
}
sum=0;
//求右子数组最大值
for(int j=mid+1;j<=high;j++){
sum+=A[j];
if(sum>right_sum){
right_sum=sum;
}
}
return (left_sum+right_sum);
}
int find_maximum_subarry(int *A,int low,int high){
if(low==high){
return A[high];
}
else{
int mid=(low+high)/2;
int left_sum=find_maximum_subarry(A,low,mid);
int right_sum=find_maximum_subarry(A,mid+1,high);
//合并过程
int corss_sum=find_max_corssing_subbary(A,low,mid,high);
int _sum=max(left_sum,max(right_sum,corss_sum));
return _sum;
}
}
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>A[i];
}
cout<<find_maximum_subarry(A,1,n);
return 0;
}