最大子段和-蛮力法
Posted xxaf
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最大子段和-蛮力法相关的知识,希望对你有一定的参考价值。
问题描诉: 给定有n个整数(可能为负整数)组成的序列a1,a2,...,an,求该序列连续的子段和的最大值和区间。 如果该子段的所有元素和是负整数时定义其最大子段和为0。
输入:1 -2 4 5 -2 8 3 -2 6 3 7 -1
输出:32 , [3 , 11]
蛮力法:
时间:O(n3)
#include<iostream> using namespace std; int main() { int a[20]; int n; int max=0; int x,y; cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; } for(int i=1;i<=n;i++) //左区间 { for(int j=i;j<=n;j++) //右区间 { int sum=0; for(int k=i;k<=j;k++) //区间内的和 { sum+=a[k]; } if(sum>max) { max=sum; x=i,y=j; } } } if(max>0) { cout<<max<<" , ["<<x<<" , "<<y<<"]"; } else { cout<<0; } return 0; }
分治法:
时间:O(n*logn)
最大子段和的区间有三种情况:
左半部分、右半部分和跨越中间部分
递归(左半部分,图片从上往下看,整体在从下往上看):
s1=左面最大子段和 s2=右面最大子段和 s3=s1+s2+他们中间的数
s1=4 s2=11 s3=15,最大子段和为15,区间【4,8】
s1=1 s2=4 s3=3,最大子段和为4,区间【4】 s1=5 s2=8 s3=11,最大子段和为11,区间【5,8】
s1=-2 s2=4 s3=2,最大子段和为4,区间【4】 s1=-2 s2=8 s3=6,最大子段和为8,区间【8】
#include<iostream> using namespace std; int MaxSubArray(int a[],int left,int right) { int mid=(left+right)/2; int s1,s2,sum=0; int max=-10000; //max相当于s3 if(left==right) { return a[left]; } s1=MaxSubArray(a,left,mid); //左递归 s2=MaxSubArray(a,mid+1,right); //右递归 for(int i=mid;i>=0;i--) //从左半部分最后一个数向前加找出最大值 { sum+=a[i]; if(max<sum) { max=sum; } } sum=max; //保留最大值 for(int i=mid+1;i<=right;i++) //从右半部分第一个数向后加找出最大值 { sum+=a[i]; if(max<sum) { max=sum; } } if(max<s1) { max=s1; } else if(max<s2) { max=s2; }return max; } int main() { int a[20]; int n; cin>>n; for(int i=0;i<n;i++) { cin>>a[i]; } cout<<MaxSubArray(a,0,n-1); return 0; }
以上是关于最大子段和-蛮力法的主要内容,如果未能解决你的问题,请参考以下文章