激光炸弹
[HNOI2003]激光炸弹
https://ac.nowcoder.com/acm/problem/20032
思路
首先题目让我们求最多能炸掉多少的目标,我们可以用F[i][j]来代表(Xi,Yi)的值,而且题目让我们求以r为边长的正方形覆盖的最大权值,很明显可以想到二维的前缀和
为什么用二维前缀和 :
就是预处理的思想,在O(1)的时间内求出二维数组中的某个矩阵的区域内的数字之和
公式
F[i][j] = F[i][j-1]+F[i-1][j]+a[i][j]-F[i-1][j-1],不过可以通过求自身的前缀和来稍稍优化下内存= =;
附蒟蒻的代码
#include <bits/stdc++.h> using namespace std; const int N = 5010; int g[N][N]; int n,r; int main () { int x,y,v; scanf("%d%d",&n,&r); int a = r,b = r; for (int i = 1 ; i <= n ; i++) { cin>>x>>y>>v; x++,y++; a = max(a,x),b = max(b,y); g[x][y]+=v; } for (int i = 1 ; i <= a ; i++) { for (int j = 1 ; j <= b ; 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 <= a ; i++) { for (int j = r ; j <= b ; 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; }