方法一:分治法求解最大子序列之和
//10 -10 1 2 3 4 -5 -23 3 7 -21
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
//蛮力法:三重循环
//第一层:起点下标
//第二层:终点下标
//第三层:计算起点到终点的值
//优化蛮力法:二重循环
//第一层:起点下标
//第二层:终点下标
//sum依次累加
//计算跨中间的最大值
int crossPartition(int left,int mid,int right,int a[]){
int lmax=INT_MIN;
int rmax=INT_MIN;
int temp=0;
for(int i=mid;i>=left;i--){
temp+=a[i];
if(temp>lmax){
lmax=temp;
}
}
temp=0;
for(int i=mid+1;i<=right;i++){
temp+=a[i];
if(temp>rmax){
rmax=temp;
}
}
return lmax+rmax;
}
//拆分成子问题
int partition(int left,int right,int a[]){
if(left>=right){
return a[left];
}else{
int mid =(left+right)/2;
int s1=partition(left,mid,a); //s1代表mid左边的最大值
int s2=partition(mid+1,right,a); //s2代表mid右边的最大值
int s3=crossPartition(left,mid,right,a);//s3代表跨中间的最大值,从mid分别向左走,向右走
vector<int>v;
v.push_back(s1);
v.push_back(s2);
v.push_back(s3);
sort(v.begin(),v.end());
return v[2];
}
}
int main(){
int num;
freopen("D:\\a.txt","r",stdin);
cin>>num;
int a[num]; //☆这里非常重要!!!一定要在num赋值之后进行数组初始化,否则数组长度为空!!10 -10 1 2 3 4 -5 -23 3 7 -21
for(int i=0;i<num;i++){
cin>>a[i];
}
int x=partition(0,num-1,a);
cout<<x;
//system("pause");
return 0;
}
方法二:动态规划法
//动态规划法
//主要思想:依次循环遍历,当temp<0时,将当前a[i]值赋予它,当temp大于0时,则累加,然后比较它与maxres的大小,使得maxres最大
int main(){
int num;
freopen("D:\\a.txt","r",stdin);
cin>>num;
int a[num]; //☆这里非常重要!!!一定要在num赋值之后进行数组初始化,否则数组长度为空!!10 -10 1 2 3 4 -5 -23 3 7 -21
int maxRes=INT_MIN;
int temp=0;
for(int i=0;i<num;i++){
cin>>a[i];
if(temp<0)temp=a[i];
else temp+=a[i];
maxRes=max(temp,maxRes);
}
cout<<maxRes;
system("pause");
return 0;
}