题目

题意:

一种炸弹可以将边长为R的正方形内的所有目标摧毁,
问一颗炸弹最多能摧毁多少价值的目标

二维前缀和:

以(1,1)为起始点,v[i][j]表示点(1,1)到点(i,j)矩阵的目标价值和。
那么如何计算v[i][j],类比一维里面 psum[i]+=psum[i-1]

右下角的位置为(i,j),左上角为(1,1)
v [i] [j-1] :(1,1)到(i,j-1)
v [i-1][j] : (1,1)到(i-1,j)
因为这两个都包括了v[i-1][j-1]

则v[i][j] = v[i][j] + v[i-1][j] + v[i][j-1] - v[i-1][j-1]

思路:

边长为R的正方形范围内,我们就枚举,以(R,R)为起点,两重for循环,枚举每个点,不断计算当前正方形内的目标价值,更新最大值

AC代码:

#include <bits/stdc++.h>

using namespace std;
const int maxn = 5000+9;
int v[maxn][maxn];
int main()
{
    int N,R;
    cin>>N>>R;
    int mx = R;//取最大范围
    int my = R;//最大范围
    for(int i=0;i<N;i++)
    {
        int x,y,v2;
        cin>>x>>y>>v2;
        x++;
        y++;
        mx = max(mx,x);
        my = max(my,y);
        v[x][y] = v2;
    }
    //计算前缀和
    for(int i=1;i<=mx;i++)
    {
       for(int j=1;j<=my;j++)
       {
            v[i][j] += v[i-1][j] + v[i][j-1] -v[i-1][j-1];
       }
    }
    int ans = -1e9;
    for(int i=R;i<=mx;i++)
    {
        for(int j=R;j<=my;j++)
        {
            ans=max(ans,v[i][j]-v[i-R][j]-v[i][j-R]+v[i-R][j-R]);
        }
    }
    cout<<ans<<endl;
    return 0;
}