链接
https://www.luogu.org/problemnew/show/P2280
大意
最大子矩阵和
给定边长至多为5000的矩阵,共有 个点有价值,求出边长为 的价值和最大的子矩阵
思路
二维前缀和
设
表示以第一行第一个格子为左上角,长宽分别为
和
所构成的子矩阵中所有元素之和
可以得到方程:
至于为什么要减,是利用了容斥原理,去掉重复的
代码
#include<cstdio>
using namespace std;
int x,y,w,n,R,maxx=5001,maxy=5001,s[5005][5005],ans;
signed main()
{
scanf("%d%d",&n,&R);
for(register int i=1;i<=n;i++)
{
scanf("%d%d%d",&x,&y,&w);
x++;y++;
s[x][y]=w;
}
for(register int i=1;i<=maxx;i++)
for(register int j=1;j<=maxy;j++)
s[i][j]=s[i][j]+s[~-i][j]+s[i][~-j]-s[~-i][~-j];//转移
for(register int i=0;i<=maxx-R;i++)
for(register int j=0;j<=maxy-R;j++)
if(s[i][j]-s[i+R][j]-s[i][j+R]+s[i+R][j+R]>ans) ans=s[i][j]-s[i+R][j]-s[i][j+R]+s[i+R][j+R];//求值
printf("%lld",ans);//输出
}