HDU1081-To The Max
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1081.
题目大意::
在给定 n*n 大小的矩阵中找出所有元素和相加最大的矩阵。
那么这道题应该怎样切入思考呢?
刚开始拿到这道题,似乎除了枚举矩阵的上下左右区间来暴力求解没什么其他思路,但这显然会超时。
这也是本题的切入点,如果我们合并压缩那些本来要枚举的行,那么就变成了求最大子段和问题。这么说可能有些难以理解,让我们来举个例子。
有这样一个3x3的矩阵:
1 -2 3
-4 5 -6
7 -8 9
他存在的最大子阵和,这个子矩阵的行数肯定是 {1},{2},{3},{1,2},{2,3},{1,2,3}中的一种,那么对于行数超过2的子矩阵,这里用{2,3}举例:
-4 5 -6
7 -8 9
对于每一列的元素例如第一列的-4 和7,要么一起加上求和,要么都不取,因此就可以看成一个元素,那么每次所枚举的任何列长的矩阵,我们都可以把同一列上的元素压缩捆绑,需要当成最大子段和问题处理即可。
压缩后:
3 -3 3
那么对于列长从i到j上元素的捆绑,最基本的做法当然就是简单的循环相加,但是这样操作效率较低,这时就要用到前缀和的应用,相当于对于1~n列上的和的预处理,代码如下:
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j]; //在输出原矩阵数据的同时顺带完成前缀和,提高效率
ans=max(ans,a[i][j]);
sum[i][j]=sum[i-1]