【题目描述】
已知矩阵的大小定义为矩阵中所有元素的和。给定一个矩阵,你的任务是找到最大的非空(大小至少是1×1)子矩阵。
【输入】
输入是一个N×N的矩阵。输入的第一行给出N(0<N≤100)。再后面的若干行中,依次(首先从左到右给出第一行的N个整数,再从左到右给出第二行的N个整数……)给出矩阵中的N2个整数,整数之间由空白字符分隔(空格或者空行)。已知矩阵中整数的范围都在[−127,127]。
【输出】
输出最大子矩阵的大小。
【输入样例】
4
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
【输出样例】
15
首先,如果这道题暴力搜索矩阵的两个端点,再依次计算矩阵和求最大(大致需要六个循环)在ybt上只能得30分,其余都会TLE
那么,我们在暴力的基础上,给这道题加个小小的优化——前缀和(只需四重循环):
关于具体的前缀和思想,请看☟☟☟
https://www.cnblogs.com/ljy-endl/p/11325425.html
虽然这样呢已经可以过了,但是精益求精的好孩子(对就是我没错)是不会就这样算了,我们进一步在前缀和的基础上加上贪心的思想(三重循环):
这样就感觉肥肠完美 (当然也可能有大佬想出了更加高级的算法)还是当我没说吧...上代码!
1 #include<bits/stdc++.h> 2 using namespace std; 3 int a[101][101]; 4 int main() 5 { 6 int n,max=-1;cin>>n; 7 for(int i=1;i<=n;i++) 8 { 9 for(int j=1;j<=n;j++) 10 { 11 cin>>a[i][j]; 12 a[i][j]+=a[i][j-1]; 13 } 14 } 15 for(int i=0;i<n;i++) 16 { 17 for(int j=i+1;j<=n;j++) 18 { 19 int ans=0; 20 for(int k=1;k<=n;k++) 21 { 22 ans+=a[k][j]-a[k][i]; 23 if(ans>max)max=ans; 24 if(ans<0)ans=0; 25 } 26 } 27 } 28 cout<<max; 29 return 0; 30 }