最大子矩阵问题 PKU 1050

题目描述:给定一个二维矩阵包含正负数,求子矩阵中的和的最大值。

例如:

0 -2 -7 0 
9 2 -6 2 
-4 1 -4 1 
-1 8 0 -2 

最大值为: 15 = 

 9 2 

-4 1

-1 8

解题思路:      [枚举上下界,转化为一维最大子序列和]

由一维最大子序列和推广至二维: 假设我们已经知道最大子矩阵所在的高度(行)的上界和下界(起点行号和终点行号,eg [first,last]),然后我们再将相应上下界中每一列的和

求出来,保存在数组b[i]中,这样就变成了求一维数组的最大子序列和的问题。

PS: 在求每列之和时,可以用一个小技巧。对于某一上界 a_first, 不同的下界 b_first 对应的每列之和 b[] 都可以由上一个枚举的下界b_first - 1中的b[] 加上当前的值得到。

int max_sum(int ar[],int n)                   //一维最大子序列和
{
    int thissum = 0, maxsum = INT_MIN;
    for (int i = 0;i < n;++i)
    {
        thissum += ar[i];
        if (thissum < 0)
        {
            thissum = 0;
        }
        if (thissum > maxsum)
        {
            maxsum = thissum;
        }
    }
    return maxsum;
}
int main()
{
    int mat[100][100];         //输入二维矩阵
    int n;
    int b[100];                     //保存相应的和
    int maxx = INT_MIN;
    int temp;
    cin>>n;
    for (int i = 0;i < n;++i)
    {
        for (int j = 0;j < n;++j)
        {
            cin>>mat[i][j];
        }
    }
    for (int i = 0;i < n;++i)             //枚举上下界     i为上界
    {
        memset(b,0,sizeof(b));              //b清零 因为不同上界对应的 列和 不一样
        for (int j = i;j < n;++j)                //枚举下界 j           [i,j]
        {
            for (int k = 0;k < n;++k)      //求相应的列和 对于同一上界i 不同下界j  b[j]总是通过上一个b[j-1]得到
            {
                b[k] += mat[j][k];             //b[j] = b[j - 1] + mat[j][]
            }
            temp = max_sum(b,n);         //求上下界[i,j]中的最大子序列和          
            if (temp > maxx)
            {
                maxx = temp;
            }
        }
    }
    cout<<maxx<<endl;
    return  0;
}
posted @ 2012-08-13 10:52  Itachi7  阅读(259)  评论(0编辑  收藏  举报