给你一个矩阵,求出这个矩形的和最大的子矩形的值
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
它的和最大的子矩阵是
9 2
-4 1
-1 8
所以值是15.
联想到之前写过leetcode上的 Largest Rectangle in Histogram这个题目以及另外一个最大0-1矩阵的题目
但是不太一样。。。
不得不说这个解法真的满巧妙,数据是N<=100,所以最多考虑n³的解法
将矩阵压缩成为一个一维的向量,然后求最大连续子数组的和的最大值即可。
求连续子数组的最大和是线性解法。
按照题目的case举例子,压缩矩阵的情况有:
1. 0 -2 -7 0
2. 0 -2 -7 0
9 2 -6 2
3. 0 -2 -7 0
9 2 -6 2
-4 1 -4 1
4. 0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
5. 9 2 -6 2
。。。。。。
以此类推总共有n*(n-1)/2种情况,所以最后是n³的解法。
#include<iostream>
#include<vector>
#include<string>
using namespace std;
int n;
int grid[101][101];
int go(vector<int> &v){
vector<int> val;
val.push_back(v[0]);
for(int i=1;i<v.size();i++){
val.push_back(max(v[i],v[i]+val[i-1]));
}
int ma = -10000;
for(int i=0;i<n;i++)
ma = max(ma,val[i]);
return ma;
}
int compute(){
vector<int> v;
int ma = -10000;
for(int k=0;k<n;k++){
for(int i=0;i<n;i++)
v.push_back(0);
for(int i=k;i<n;i++){
for(int j=0;j<n;j++)
v[j]+=grid[i][j];
ma = max(ma,go(v));
}
v.clear();
}
return ma;
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++)
cin>>grid[i][j];
}
cout<<compute()<<endl;
}