题目
设A=<a1,a2,...,an>是n个整数的序列,称<ai,....,aj>为该序列的连续子序列,其中1<=i<=j<=n,子序列的元素之和称为A的子段和:
例如,A=<-2,11,-4,13,-5,-2>,那么它的子段和如下:
长度为1的子段和有:-2,11,-4,13,-5,-2
长度为2的子段和有:9,7,9,8,-7
长度为3的子段和有:5,20,4,6
长度为4的子段和有:18,15,2
长度为5的子段和有:13,13
长度为6的子段和有:11
其中的最大子段和为:11-4+13=20
则最大子段和问题为:
给定n个整数的序列A=<a1,a2,...,an>,求最大子段和
//分治法 最大子段可能在左边 右边或者是中间出现
#include "iostream"
using namespace std;
const int N = 1e3;
int a[N];
int LargeSum(int l, int r) {
if(l == r){
int t = a[l] > 0 ? a[l] : 0;
return t;
}
int mid = l + r >> 1;
int ls = LargeSum(l, mid);
int rs = LargeSum(mid + 1, r);
int s1 = 0;
int left = 0;
for(int i = mid; i >= l; i --){
left += a[i];
if(left > s1) s1 = left;
}
int s2 = 0;
int right = 0;
for(int i = mid + 1; i <= r; i ++){
right += a[i];
if(right > s2) s2 = right;
}
int sum = s1 + s2;
if(ls > sum) sum = ls;
if(rs > sum) sum = rs;
return sum;
}
int main(){
int n;
cin >> n;
for(int i = 0; i < n; i++){
cin>>a[i];
}
cout<<LargeSum(0, n - 1);
return 0;
}
//动态规划解决问题
#include "iostream"
using namespace std;
int f[100];
int main(){
int n;
int a[100];
cin>>n;
for(int i = 0; i < n; i++){
cin>>a[i];
}
int b = 0;
int max = 0;
for(int i = 0; i < n; i ++){
if(f[i] > 0){
f[i + 1] = f[i] + a[i];
}
else f[i + 1] = a[i];
if(f[i + 1] > max ) max = f[i + 1];
}
// for(int i = 0; i < n; i ++){
// b = b > 0? b + a[i] : a[i];
// max = b > max : b : max;
// } //第二种方法
cout<<max;
return 0;
}