最大子数组(C语言)

来源:互联网 发布:windows键盘option键 编辑:程序博客网 时间:2024/05/21 17:19

1.暴力求解

#include <stdio.h>int subset_direct(int *A,int n){    int sum_max = -99999;    for(int i=0;i<n;i++){        int sum = 0;        for(int j=i;j<n;j++){            sum = sum+A[j];            if(sum>sum_max){                sum_max = sum;            }        }    }    return sum_max;}int main(){    int A[]={1,2,8,-3,-8,-2,6,10,5,-6};    printf("%d\n",subset_direct(A,10));    return 0;}

2.分治策略

#include <stdio.h>int max_num(int a,int b,int c)//返回3个数中的最大值{    int max;    max = a;    if(max<b)        max = b;    if(max<c)        max = c;    return max;}int max_subset(int A[],int left,int right){    int mid,i;    int max_left,max_right;//左半部分和右半部分最大值    int max_left_border=0,max_right_border=0;//包括左边界和右边界的最大值    int sum_left_border=0,sum_right_border=0;//包括左边界和右边界的值    if(left==right){        return A[left];    }    mid = (left+right)/2;    max_left = max_subset(A,left,mid);    max_right = max_subset(A,mid+1,right);    for(i=mid;i>=left;i--){        sum_left_border += A[i];        if(sum_left_border>max_left_border){            max_left_border = sum_left_border;        }    }    for(i=mid+1;i<=right;i++){        sum_right_border += A[i];        if(sum_right_border>max_right_border){            max_right_border = sum_right_border;        }    }    return max_num(max_left,max_right,max_left_border+max_right_border);}int main(){    int A[] = {1,2,8,-3,-8,-2,6,10,5,-6};    int max;    max = max_subset(A,0,9);    printf("%d ",max);    return 0;}

3.线性求解

#include <stdio.h>int linear_subset(int A[],int n){    int i;    int temp = 0;    int max_sum = 0;    for(i=0;i<n;i++){        temp +=A[i];        if(temp>max_sum){            max_sum = temp;        }        if(temp<0){            temp = 0;        }    }    return max_sum;}int main(){    int A[] = {1,2,8,-3,-8,-2,6,10,5,-6};    int max;    max = linear_subset(A,10);    printf("%d ",max);    return 0;}

关于线性求解,我自己也说不清楚,需要自己多琢磨。
如果a[1..j]已经得到了其最大子数组,那么a[1..j+1]最大子数组只能是两种情况
(1)a[1..j+1]的最大子数组就是a[1..j];
(2)a[1..j+1]的最大子数组是a[i..j+1],1<=i<=j;
那么,如何求得所谓的(2)中的a[i..j+1]呢?
首先需要承认这样的事实,如果一个数组a[p..r]求和得到负值,那么数组a[p..r+1]的最大子数组肯定不会是a[p..r+1],因为a[p..r]+a[r+1]

1 1