前缀和
首先来讲下什么是一维前缀和
假设有一数组a1,a2,a3,a4,a5,an
s1=a1,s2=a1+a2,sn=a1+…+an
s数组就是a数组的前缀和,那么前缀和有什么用呢?
用于求一段区间的值,列如a5–a15区间内的值等于s15-s4,就比较好理解!!
二维前缀和
一维数组能对其求前缀和,那么二维矩阵也能对其求前缀和!
如果我们想求红色矩阵内的元素值,可以发现同样可以通过前缀和相减获得
那么如何求前缀和呢??
s[i][j]=g[i][j]+s[i-1][j]+s[i][j-1]-s[i-1][j-1];
由图推导出前缀和的公式就是当前点加上前面的前缀和减去重复的部分!!
以下是二维前缀和的模板题!!!
AcWing 99. 激光炸弹
#include<bits/stdc++.h>//最大O(n^2)
using namespace std;
const int N=5005;
int g[N][N];//存储值转化为二维前缀和
int main(){
memset(g,0,sizeof(g));
int n,r;
cin >> n >> r;
int nn=r,mm=r;//确定边界
for(int i=1;i<=n;i++){
int x,y,w;
cin >> x >> y >> w;
x++;//下标从一开始
y++;
nn=max(x,nn);
mm=max(y,mm);
g[x][y]+=w;
}
for(int i=1;i<=nn;i++)
for(int j=1;j<=mm;j++)
g[i][j]+=g[i-1][j]+g[i][j-1]-g[i-1][j-1];//求二维前缀和
int res=0;
for(int i=r;i<=nn;i++){
for(int j=r;j<=mm;j++){
res=max(res,g[i][j]-g[i-r][j]-g[i][j-r]+g[i-r][j-r]);//枚举
}
}
cout << res << endl;
return 0;
}