对于一维的数组,要求其子数组之和的最大值很简单,动态规划轻松解决,复杂度O(N)
代码如下:
#include <iostream>
using namespace std;
int MaxSum(int a[],int n)
{
int start = a[0];
int max = a[0];
for(int i=1;i<n;i++)
{
if(start<0)
start = 0;
start += a[i];
if(start>max)
max = start;
}
return max;
}
int main()
{
int a[] = {1,2,-4,3,5,7,-5,6};
cout<<MaxSum(a,8);
return 0;
}
但是对于二维的数组要求其子数组之和的最大值就困难很多了,具体方法可参看《编程之美》2.15节,其实就是将二维的问题化成一维的来解决
代码可参看:
#include <iostream>
using namespace std;
#define M 5
#define N 5
int PS[M+1][N+1];
int BC(int a,int c,int i)
{
return PS[c][i]-PS[a-1][i]-PS[c][i-1]+PS[a-1][i-1];
}
int MaxSum(int A[M][N])
{
for(int i=0;i<=M;i++)
PS[i][0]=0;
for(int j=0;j<=N;j++)
PS[0][j] =0;
for(int i=1;i<=M;i++)
for(int j=1;j<=N;j++)
PS[i][j] = PS[i-1][j]+PS[i][j-1]-PS[i-1][j-1]+A[i-1][j-1];
int max = -10000;
for(int a=1;a<=M;a++)
for(int c=1;c<=N;c++)
{
int start = BC(a,c,M);
int all = BC(a,c,M);
for(int i=M-1;i>=1;i--)
{
if(start<0)
start = 0;
start += BC(a,c,i);
if(start>all)
all = start;
}
if(all>max)
max = all;
}
return max;
}
int main()
{
int a[M][N] = {-1,-2,-3,-4,-5,-3,4,5,6,-9,-12,44,32,7,-8,-3,22,56,78,-6,-5,2,3,7,-1};
cout<< MaxSum(a);
return 0;
}
其实就是化成M*N个一维的问题来解决的