1.最大子段和
定义数组b[j]用来记录一j为尾的子段和集合中的最大子段和。
由b[j]的定义易知,当b[j-1]>0时,b[j] = b[j-1] + a[j],否则 b[j] = a[j]。
由此可得计算b[j]的动态规划递归式
b[j] = max{ b[j-1] + a[j] , a[j] }, 1<=j<=n.
算法实现:
public class MaxSum {
public static int maxSum(int[] a){
int b,sum;
b=a[0]>0?a[0]:0;
sum=b;
for(int j=1;j<a.length;j++){
if(b>0)
b+=a[j];
else
b=a[j];
if(b>sum)
sum=b;
}
return sum;
}
public static void main(String[] args) {
int sum=maxSum(new int[]{-2,11,-4,13,-5,-2});
System.out.println("最大子段和="+sum);
}
}
最大子段和=20
2.最大子矩阵和
如果我们将从第i行到第j行的每一行中相同列的加起来,可以得到一个一维数组,记为b[k],由此我们可以看出最后所求的就是此一维数组的最大子段和问题,枚举从i到j行的所有可能,就可以求出最大矩阵和。
代码实现:
public static int maxMatrix(int[][] array){
int m=array.length;
int n=array[0].length;//mxn的矩阵
int sum1=0;
int[] b= new int[n];//辅助数组b
for(int i=0;i<m;i++){
for(int k=0;k<n;k++){//起始行i变化,重新初始化b[k]
b[k]=0;
}
for(int j=i;j<m;j++){//从第i行到第j行
for(int k=0;k<n;k++){
b[k]+=array[j][k];//b[k]表示数组array第k列,从第i行到第j行的和
}
int max1=maxSum(b);//每确定一个i,j,会填充数组b,求得b的最大子段和
if(max1>sum1)
sum1=max1;
}
}
return sum1;
}
public static void main(String[] args) {
int[][] array = new int[][]{{0,-2,-7,0},
{9, 2,-6,2},
{-4,1,-4,1},
{-1,8, 0,-2}
};
System.out.println("最大子矩阵和="+maxMatrix(array));
}
最大子矩阵和=15