最大子段和(分治法)

Description

给定有n个整数(可能为负整数)组成的序列a1,a2,...,an,求该序列连续的子段和的最大值。 如果该子段的所有元素和是负整数时定义其最大子段和为0。

Input

第一行有一个正整数n(n<1000),后面跟n个整数,绝对值都小于10000。直到文件结束。

Output

输出它的最大子段和。

Sample Input

6 -2 11 -4 13 -5 -2

Sample Output

20

分别用普通O(n 3 )或O(n 2 )、分治O(nlogn)和动态规划O(n)实现。做出后可以再做 To the Max

 

思路:往左边和右边递归找一个最大,但是最大字段和还会出现在递归的两边,所以在往左往右递归的同时从mid往左和往右用for循环找一个最大,然后再找递归最大。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
#define MAX 1e9+7
#define inf 0x3f3f3f
const int M=1e3+10;
typedef long long ll;
int a[M],n;
int MM(int left,int right){
    if(left==right)
        return max(a[left],0);
    int mid=(left+right)/2;
    int max1=MM(left,mid);
    int max2=MM(mid+1,right);
    int sum1=0,sum2=0;
    int m1=0,m2=0;
    for(int i=mid;i>=0;i--){//往左边找一个最大
        sum1+=a[i];
        m1=max(sum1,m1);
    }
    for(int i=mid+1;i>n){
        for(int i=0;i>a[i];
        int maxx=0;
        maxx=MM(0,n-1);
        cout<

方法二:

#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
using namespace std; 
#define MAX 1e9+7 
#define inf 0x3f3f3f 
const int M=1e3+10; 
typedef long long ll; 
int a[M]; 
int sum[M]; 
int main() 
{ 
    int n; 
    while(cin>>n){ 
        memset(a,0,sizeof(a)); 
        memset(sum,0,sizeof(sum)); 
        for(int i=1;i<=n;i++){ 
            cin>>a[i]; 
            sum[i]=sum[i-1]+a[i]; 
        } 
        int maxx=0; 
        for(int i=1;i<=n;i++){ 
            for(int j=i;j<=n;j++){ 
               // cout<

 

你可能感兴趣的:(ACM程序设计基础)