Description
一种新型的激光炸弹,可以摧毁一个边长为R的正方形内的所有的目标。现在地图上有n(N<=10000)个目标
,用整数Xi,Yi(其值在[0,5000])表示目标在地图上的位置,每个目标都有一个价值。激光炸弹的投放是
通过卫星定位的,但其有一个缺点,就是其爆破范围,即那个边长为R的正方形的边必须和x,y轴平行。若
目标位于爆破正方形的边上,该目标将不会被摧毁。
Input
输入文件的第一行为正整数n和正整数R,接下来的n行每行有3个正整数,分别表示xi,yi,vi
Output
输出文件仅有一个正整数,表示一颗炸弹最多能炸掉地图上总价值为多少的目标(结果不会超过32767)。
Sample Input
2 1
0 0 1
1 1 1
Sample Output
1
维护一个二位前缀和数组
v a l [ i ] [ j ] val[i][j] val[i][j]代表从 i , j i,j i,j开始到 [ 1 , 1 ] [1,1] [1,1] 的前缀和
根据集合的容斥原理有推导公式
v a l [ i ] [ j ] + = v a l [ i − 1 ] + v a l [ i ] [ j − 1 ] − v a l [ i − 1 ] [ j − 1 ] val[i][j]+=val[i-1]+val[i][j-1]-val[i-1][j-1] val[i][j]+=val[i−1]+val[i][j−1]−val[i−1][j−1]
对于从 [ i , j ] [i,j] [i,j]开始面积为k的前缀和有公式
S = v a l [ i ] [ j ] − v a l [ i − k ] [ j ] − v a l [ i ] [ j − k ] + v a l [ i − k ] [ j − k ] S=val[i][j]-val[i-k][j]-val[i][j-k]+val[i-k][j-k] S=val[i][j]−val[i−k][j]−val[i][j−k]+val[i−k][j−k]
#include <vector>
#include <iostream>
using namespace std;
static const auto io_sync_off = []() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
return nullptr;
}();
const int maxn = 5005;
int val[maxn][maxn];
int main()
{
int n, k, r, c; //n个数,k的面积,长宽范围
cin >> n >> k;
r = c = k;
for (int i = 0; i < n; ++i)
{
int x, y, z;
cin >> x >> y >> z;
++x, ++y;
r = max(x, r), c = max(y, c);
val[x][y] = z;
}
// 计算前缀和
for (int i = 1; i <= r; ++i)
for (int j = 1; j <= c; ++j)
val[i][j] += val[i - 1][j] + val[i][j - 1] - val[i - 1][j - 1];
// 枚举所有面积为k的情况
int ans = 0;
for (int i = k; i <= r; ++i)
for (int j = k; j <= c; ++j)
ans = max(ans, val[i][j] - val[i - k][j] - val[i][j - k] + val[i - k][j - k]);
cout << ans << endl;
return 0;
}