您的位置:首页 > 其它

最大子矩阵问题 PKU 1050

2012-08-13 10:52 204 查看
题目描述:给定一个二维矩阵包含正负数,求子矩阵中的和的最大值。

例如:

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: