简单动规 最大子矩阵和

问题:

一个M*N的矩阵,找到此矩阵的一个子矩阵,并且这个子矩阵的元素的和是最大的,输出这个最大的值。
例如:3*3的矩阵:

-1 3 -1
2 -1 3
-3 1 2

和最大的子矩阵是:

3 -1
-1 3
1 2
Input第1行:M和N,中间用空格隔开(2 <= M,N <= 500)。 
第2 - N + 1行:矩阵中的元素,每行M个数,中间用空格隔开。(-10^9 <= M ii <= 10^9) Output输出和的最大值。如果所有数都是负数,就输出0。 Sample Input
3 3
-1 3 -1
2 -1 3
-3 1 2
Sample Output
7

思路:

这个题其实是最大子段和的一个拓展,我们把矩阵按行分为若干个子矩阵,例如一个3*3的矩阵,就被分成了第一行,第二行,第三行,第一二行,第二三行...这么多矩阵,这些子矩阵肯定是包含最大子矩阵的,又例如,假设最大子矩阵位于该矩阵的第1行到第二行,第二列到第三列(也就是右上角的四个数),那么前边按行分的子矩阵中第一二行的子矩阵就包含了最大子矩阵,只是比最大子矩阵多了第一列,这样既然二者是包含关系,那么最大子矩阵所在的按行分的子矩阵和肯定也是最大的,最大子矩阵由于行,列都未知,不易列举,但按行划分的矩阵就好列举了。那么怎么求按行分的子矩阵和呢?这就用到了最大子段和的思路:对每一个按行划分的子矩阵,把每一列都加起来,得到一个序列,求这段序列的最大子段和,然后从这几个和中找出最大的,就得到答案了。

代码:

#include 
#include 
int maxseq(long int a[],long int n)//求最大子段和
{
    long int now,max;
    int i;
    max=now=a[0];
    for(i=1; imax)
            max=now;
    }
    return max;
}
int main()
{
    int i,j,k,m,n;
    long int ju[500][500],a[500],max_m,max_s;//a数组记录按列相加后的序列
    while(scanf("%d%d",&m,&n)!=EOF)
    {
        max_m=0;
        for(i=0; imax_m)
                    max_m=max_s;
            }
        }
        if(max_m<0)
            max_m=0;
        printf("%ld\n",max_m);
    }
    return 0;
}




你可能感兴趣的:(简单dp)