崩 oj 1768 最大子矩阵
描述
已知矩阵的大小定义为矩阵中所有元素的和。给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵。
比如,如下4 * 4的矩阵
0 -2 -7  0  9  2 -6  2 -4  1 -4  1 -1  8  0 -2
的最大子矩阵是
9  2 -4  1 -1  8
这个子矩阵的大小是15。
输入
输入是一个N * N的矩阵。输入的第一行给出N (0 < N <= 100)。再后面的若干行中,依次(首先从左到右给出第一行的N个整数,再从左到右给出第二行的N个整数……)给出矩阵中的N2个整数,整数之间由空白字符分隔(空格或者空行)。已知矩阵中整数的范围都在[-127, 127]。
输出
输出最大子矩阵的大小。
=======================================================================================================================================================================================================================
刚拿到这道题的时候 一点思路也没有
所以....
我搜题解去了
(好吧...这样不好)
发现一种更有意思的东西
矩阵前缀和
在这里先简单点儿
--------------------------------------------
就在下面
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
(a:元素,sum:从a(1,1)到a(i,j)所有值的和,就是前缀和。)

边读入边求前缀和(sum),用这个公式来求:①+②+③-④ 得出sum(5,3)=a(5,3)+sum(4,2)+sum(5,2)-sum(4,2);
好像有点递推思想呢?
然后四重循环暴力枚举所有子矩阵,找到最大值!

公式:①-②-③+④,枚举出(2,2)到(5,3)的矩阵大小t=sum(5,3)-sum(5,1)-sum(1,3)+sum(1,1),更新最大值。
这时候 就稍稍有点思路了
以下是代码:
#include<cstdio>
#include<algorithm>
using namespace std;
int n,b[110][110],a[110][110],maxn,q,w,e,r;
int main()
{
 scanf("%d",&n);
 for(int i=1;i<=n;++i)
  for(int j=1;j<=n;++j)
  {
   scanf("%d",&a[i][j]);
   b[i][j]= a[i][j] + b[i-1][j] + b[i][j-1] - b[i-1][j-1];   //算出1.1到i.j矩阵所有元素的和 
  }
 for(q = 1;q <= n;++q) 
  for(w = 1;w <= n;++w)  
   for(e = 1;e <= q;++e)  
    for(r = 1;r <= w;++r)  
    {
     maxn=max(maxn,b[q][w] + b[e-1][r-1] - b[q][r-1] - b[e-1][w]);   //反向想 算出e.r到q.w之间矩阵的元素和 并和先已知的最大值比较 若比它大 就替换 
 printf("%d",maxn);
 return 0;
}
无后效性:
每个位置上的元素是确定的 得到的矩阵的最大值不会影响元素的值
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号