Problem Description
给你一个m×n的整数矩阵,在上面找一个x×y的子矩阵,使子矩阵中所有元素的和最大。
Input
输入数据的第一行为一个正整数T,表示有T组测试数据。每一组测试数据的第一行为四个正整数m,n,x,y(0<m,n<1000 AND 0<x<=m AND 0<y<=n),表示给定的矩形有m行n列。接下来这个矩阵,有m行,每行有n个不大于1000的正整数。
Output
对于每组数据,输出一个整数,表示子矩阵的最大和。
Sample Input
1
4 5 2 2
3 361 649 676 588
992 762 156 993 169
662 34 638 89 543
525 165 254 809 280
Sample Output
2474
这是一道二维树状数组模板题。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 1005;
typedef long long ll;
int m, n;
int c[MAXN][MAXN];
int lowbit(int x) {
return x&(-x);
}
void add(int x, int y, int p) {
while(x <= n) {
for(int i = y; i <= m; i += lowbit(i)) {
c[x][i] += p;
}
x += lowbit(x);
}
}
ll sum(int x, int y) {
ll result = 0;
while(x > 0){
for(int i = y; i > 0; i -= lowbit(i)) {
result += c[x][i];
}
x -= lowbit(x);
}
return result;
}
int main() {
int t, a, b, q;
cin>>t;
while(t--) {
memset(c, 0, sizeof(c));
cin>>m>>n>>a>>b;
for(int i = 1; i <= m; i++) {
for(int j = 1; j <= n; j++) {
cin>>q;
add(i, j, q);
}
}
ll mx = 0;
for(int i = a; i <= m; i ++) {
for(int j = b; j <= n; j++) {
ll temp = sum(i, j) - sum(i - a, j) - sum(i, j - b) + sum(i - a, j- b);
mx = max(mx, temp);
}
}
cout<<mx<<endl;
}
return 0;
}
扫描二维码关注公众号,回复:
2439745 查看本文章