求数组的子数组之和的最大值

1.一维数组

(1)分治(Divide and Conquer,DC)

#include<iostream>
#include<climits>
using namespace std;
#define n 7

void find_max_crossing_subarray(int A[],int low,int mid,int high,int &left,int &right,int &sum)
{
    int left_sum=INT_MIN,subsum=0;
    for(int i=mid;i>=low;i--)
    {
        subsum+=A[i];
        if(subsum>left_sum)
        {
            left_sum=subsum;
            left=i;
        }
    }
    int right_sum=INT_MIN;subsum=0;
    for(int j=mid+1;j<=high;j++)
    {
        subsum+=A[j];
        if(subsum>right_sum)
        {
            right_sum=subsum;
            right=j;
        }
    }
    sum=left_sum+right_sum;
}

void find_maximum_subarray(int A[],int low,int high,int &left,int &right,int &sum)
{
    if(low==high)
    {
        left=low;
        right=high;
        sum=A[low];
    }
    else 
    {
        int mid=(low+high)/2,left1,right1,sum1,left2,right2,sum2,left3,right3,sum3;
        find_maximum_subarray(A,low,mid,left1,right1,sum1);
        find_maximum_subarray(A,mid+1,high,left2,right2,sum2);
        find_max_crossing_subarray(A,low,mid,high,left3,right3,sum3);
        if(sum1>=sum2&&sum1>=sum3)
        {
            left=left1;
            right=right1; 
            sum=sum1;
        }
        else if(sum2>=sum1&&sum2>=sum3)
        {
            left=left2;
            right=right2; 
            sum=sum2;
        }
        else
        {
            left=left3;
            right=right3; 
            sum=sum3;
        }
    } 
} 

int main()
{
    int A[n]={-2,5,3,-6,4,-8,6},left,right,sum;
    find_maximum_subarray(A,0,n-1,left,right,sum);
    cout<<left<<" "<<right<<" "<<sum<<endl;
    return 0;
}
(2)动态规划(Dynamic Programming,DP)


#include<iostream>
using namespace std;

int find_maximum_subarray(int *a,int n)
{
    int g=a[0],f=a[0],i;
    for(i=1;i<n;i++)
    {
        g=max(g+a[i],a[i]);
        f=max(f,g);
    }
    return f;
}

int main()
{
    int a[7]={-2,5,3,-6,4,-8,6};
    cout<<find_maximum_subarray(a,7)<<endl;
    return 0;
}

#include<iostream>
using namespace std;

int find_minimum_subarray(int *a,int n)
{
    int g=a[0],f=a[0],i;
    for(i=1;i<n;i++)
    {
        g=min(g+a[i],a[i]);
        f=min(f,g);
    }
    return f;
}

int main()
{
    int a[7]={-2,5,3,-6,4,-8,6};
    cout<<find_maximum_subarray(a,7)<<endl;
    return 0;
}

(3)Gas Station (Leetcode)

http://www.cnblogs.com/felixfang/p/3814463.html

int canCompleteCircuit1(int gas[],int cost[],int n)
{
	int total=0,sum=0,start=0;
	for(int i=0;i<n;++i)
	{
		total+=gas[i]-cost[i];
		sum+=gas[i]-cost[i];
		if(sum<0)
		{
			sum=0;
			start=i+1;
		}
	}
	return total<0?-1:start;
}

int canCompleteCircuit2(int gas[],int cost[],int n)
{
	int total,f,g,p,q,f_index,g_index,p_index,diff;
	total=f=g=p=q=gas[0]-cost[0];
	f_index=g_index=p_index=0;
	for(int i=1;i<n;++i)
	{
		diff=gas[i]-cost[i];
		total+=diff;
		if(g<0)
		{
			g=diff;
			g_index=i;
		}
		else g+=diff;
		if(f<g)
		{
			f=g;
			f_index=g_index;
		} 
                if(q>0)q=diff;
		else q+=diff;
		if(p>q)
		{
			p=q;
			p_index=i;
		} 
	}
	return total<0?-1:(f>total-p?f_index:p_index+1);
}

2.二维数组

#include<iostream>  
#include<limits>
using namespace std;
#define m 5
#define n 5
int PS[m+1][n+1];

void partial_sum(int B[][n])
{
    int i,j;
    for(i=0;i<=m;i++)PS[i][0]=0;
    for(j=1;j<=n;j++)PS[0][j]=0;
    for(i=1;i<=m;i++)
    {
        for(j=1;j<=n;j++)
        {
            PS[i][j]=PS[i-1][j]+PS[i][j-1]-PS[i-1][j-1]+B[i-1][j-1];
        }
    }
}

int BC(int a,int c,int i)  
{  
    return  PS[c+1][i+1]-PS[a][i+1]-PS[c+1][i]+PS[a][i]; 
}  
  
int max_sum()  
{  
    int a,c,f,g,i,maximum=INT_MIN;   
    for(a=0;a<m;a++)  
    {  
        for(c=a;c<m;c++)  
        {
            f=BC(a,c,n-1);
            g=BC(a,c,n-1);
            for(i=n-2;i>=0;i--)
            {
                g=max(g+BC(a,c,i),BC(a,c,i));
                f=max(f,g);
            }
            if(f>maximum)maximum=f;
        }
    }
    return maximum;
}  
  
int main()  
{  
    int B[m][n]={{2,0,8,0,2},      
                 {0,0,0,0,0},      
                 {0,3,2,0,0},      
                 {0,0,0,0,0},      
                 {2,0,8,0,2}};
    partial_sum(B);	
    cout<<max_sum()<<endl;  
    return 0;  
} 




你可能感兴趣的:(求数组的子数组之和的最大值)