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

来源:互联网 发布:最优化理论的实例 编辑:程序博客网 时间:2024/06/05 09:39

1.一维数组

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

#include<iostream>#include<climits>using namespace std;#define n 7void 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 5int 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;  } 




0 0
原创粉丝点击