题目描述
在幻想乡,射命丸文是以偷拍闻名的鸦天狗。当然,文文的照相机可不止能够照相,还能够消除取景框里面所有的弹幕。假设现在文文面前有一块N行M列的弹幕群,每一个单位面积内有分值有num[i][j]
的弹幕。相机的取景框可以将一块R行C列的弹幕消除,并且得到这一块区域内所有弹幕的分值(累加)。现在文文想要取得尽可能多的分值,请你计算出她最多能够得到的分值。
输入描述
第1行:4个正整数N,M,R,C
第2..N+1行:每行M个正整数,第i+1行第j个数表示num[i][j]
输出描述
第1行:1个整数,表示文文能够取得的最大得分
样例输入
3 5 2 3
5 2 7 1 1
5 9 5 1 5
3 5 1 5 3
样例输出
33
数据范围
对于60%的数据:1 <= N,M <= 200
对于100%的数据:1 <= N,M <= 1,000 1 <= R <= N, 1 <= C <= M 1 <= num[i][j] <= 1000
保证结果不超过2,000,000,000
用二维前缀和解,n^2预处理,n^2枚举矩形,O(1)查询
注意对于边界的处理
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAXN = 1000 + 5;
int map[MAXN][MAXN];
int n,m;
int r,c;
void get_sum()
{
for(int i = 1;i <= n;i ++)
for(int j = 1;j <= m;j ++)
map[i][j] += map[i - 1][j] + map[i][j - 1] - map[i - 1][j - 1];
return;
}
int sum(int a,int b,int c,int d)
{
if(a < c)
swap(a,c);
if(b < d)
swap(b,d);
return map[a][b] - map[c - 1][b] - map[a][d - 1] + map[c - 1][d - 1];
}
int main()
{
scanf("%d %d %d %d",&n,&m,&r,&c);
for(int i = 1;i <= n;i ++)
for(int j = 1;j <= m;j ++)
scanf("%d",&map[i][j]);
get_sum();
int ans = 0;
for(int i = 1;i <= n - r + 1;i ++)
for(int j = 1;j <= m - c + 1;j ++)
ans = max(ans,sum(i,j,i + r - 1,j + c - 1));
printf("%d\n",ans);
return 0;
}
关于二维前缀和
sum[i][j]
表示
修改的话套个BIT(和这个题无关)
引用下神犇的课件
这个题查询时一样的,可暴力枚举两端点
嗯,就是这样了