问题虫洞:最大子矩阵 HDU - 1559
黑洞内窥:
给出n *m的矩阵,求x *y的子矩阵的最大值。
思维光年:
构建二维前缀和矩阵,设a[ i ] [ j ] 为从a[0][0] 到 a[ i ] [ j ] 的子矩阵的矩阵和,,,,那么问题就可以转换为;
maxx = max(maxx, a[i+x-1][j+y-1]-a[i+x-1][j-1]-a[i-1][j+y-1]+a[i-1][j-1]); //减掉重复的矩阵和。
感觉这个复杂度也是O((n-x)*(m-y))的。。。。反正它不会T/。。。。
AC代码:
//#include<bits/stdc++.h>
#include <stdio.h>
#include <iostream>
#include<algorithm>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <string>
#include <math.h>
#include <vector>
#include <cstring>
#include <stdlib.h>
#include <string.h>
using namespace std;
typedef long long ll;
#define MAXN 1005
#define INF 0x3f3f3f3f//将近ll类型最大数的一半,而且乘2不会爆ll
const ll mod = 1000000007;
#define mem(a, b) memset(a, b, sizeof(a))
ll a[MAXN][MAXN];
int main ()
{
ll n, m, x, y, z, t;
cin >> t;
while(t--)
{
mem(a, 0);
ll maxx = 0;
scanf("%lld %lld %lld %lld", &n, &m, &x, &y);
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j)
{
scanf("%lld", &z);
a[i][j] = a[i][j-1]+z; //每行的前缀和
}
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j)
a[i][j]+=a[i-1][j];//子矩阵i*j的和
for(int i=1; i<=n-x+1; ++i)
for(int j=1; j<=m-y+1; ++j)
maxx = max(maxx, a[i+x-1][j+y-1]-a[i+x-1][j-1]-a[i-1][j+y-1]+a[i-1][j-1]);
cout << maxx << '\n';
}
return 0;
}
OJ上的一道暴力子矩阵的题: 1273.WY的矩阵
黑洞内窥:
求最大子矩阵的和;
思维光年:
思路啥的,暴力就可以了
ACcode:
//#include<bits/stdc++.h>
#include <stdio.h>
#include <iostream>
#include<algorithm>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <string>
#include <math.h>
#include <vector>
#include <cstring>
#include <stdlib.h>
#include <string.h>
using namespace std;
typedef long long ll;
#define MAXN 1005
#define INF 0x3f3f3f3f//将近ll类型最大数的一半,而且乘2不会爆ll
const ll mod = 1000000007;
#define mem(a, b) memset(a, b, sizeof(a))
ll a[MAXN][MAXN];
int main ()
{
ll n, z;
mem(a, 0);
ll maxx = 0;
scanf("%lld", &n);
for(int i=1; i<=n; ++i)
for(int j=1; j<=n; ++j)
{
scanf("%lld", &z);
a[i][j] = a[i][j-1]+z; //每行的前缀和
}
for(int i=1; i<=n; ++i)
for(int j=1; j<=n; ++j)
a[i][j]+=a[i-1][j];//子矩阵i*j的和
for(int x=1; x<=n; ++x)//暴力部分
for(int y=1; y<=n; ++y)
for(int i=1; i<=n-x+1; ++i)
for(int j=1; j<=n-y+1; ++j)
maxx = max(maxx, a[i+x-1][j+y-1]-a[i+x-1][j-1]-a[i-1][j+y-1]+a[i-1][j-1]);
cout << maxx << '\n';
return 0;
}