PKU1050 To the Max
参考资料:
题目的意思很简单,在一个矩阵里面找它的子矩阵,使得子矩阵数值之和到达最大。其实就是最大子段和问题在二维空间上的推广。先说一下一维的情况吧:设有数组a0,a1…an,找除其中连续的子段,使它们的和达到最大。假如对于子段:9 2 -16 2 temp[i]表示以ai结尾的子段中的最大子段和。在已知temp[i]的情况下,求temp [i+1]的方法是:
如果temp[i]>0 temp [i+1]= temp[i]+ai(继续在前一个子段上加上ai),否则temp[i+1]=ai(不加上前面的子段),也就是说 状态转移方程:
temp[i] = (temp[i-1]>0?temp[i-1]:0)+buf[i];
对于刚才的例子 temp: 9 11 -5 2,然后取temp[]中最大的就是一维序列的最大子段。求一维最大子段和的函数:
int getMax(int buf[100],int n)
{
int temp[101],max=n*(-127);
memset(temp,0,4*(n+1));
for(int i=1;i<=n;i++)
{
temp[i] = (temp[i-1]>0?temp[i-1]:0)+buf[i];//因一直是temp[i]与temp[i-1]比较,故根本不需要用数组,直接一个b就搞定,b=(b>0)?b:0)+buf[i];
if(max<temp[i])
max=temp[i];
}
return max;
}
下面扩展到二维的情况:考察下面题目中的例子:
0 -2 -7 0
9 2 -6 2
-4 1 -4 7
-1 8 0 -2
我们分别用i j表示起始行和终止行,遍历所有的可能:
for(i=1;i<=n;i++)
for(j=i;j<=n;j++) {}
我们考察其中一种情况 i=2 j=4,这样就相当与选中了2 3 4三行,求那几列的组合能获得最大值,由于总是 2 3 4行,所以我们可以将这3行”捆绑”起来,变为求 4(9-4-1),11(8+2+1),-10(-6-4+0),7(7+2-2)的最大子段和,ok,问题成功转化为一维的情况!
主要思路:枚举法,枚举最大子矩阵的开始行和结束行,并求出它们之间的最大和
改过后的代码://184K 0MS 403B