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;
}