1. 激光炸弹问题背景解析
激光炸弹问题源自《算法竞赛进阶指南》中的经典例题,它巧妙地将二维前缀和与差分算法应用于实际场景。题目描述的是:在一个N×N的网格上分布着若干目标点,每个点有其价值。现在需要放置一个R×R的正方形炸弹,求炸弹覆盖区域内目标点总价值的最大值。
这个问题看似简单,但直接暴力求解的时间复杂度高达O(N^4),对于N=5000的典型数据规模完全不可行。而通过二维前缀和优化,我们可以将时间复杂度降至O(N^2),这正是算法竞赛中典型的空间换时间策略。
提示:在实际竞赛中,N=5000时,O(N^2)算法需要处理25,000,000次运算,这在现代CPU上大约需要0.5秒,刚好满足时间限制。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 二维前缀和核心原理
2.1 基本概念与构建
二维前缀和的核心思想是预处理一个与原始网格大小相同的数组sum,其中sum[i][j]表示从(1,1)到(i,j)矩形区域内所有元素的和。构建公式为:
cpp复制sum[i][j] = sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1] + matrix[i][j]
这个公式通过容斥原理避免了重复计算:将上方和左方的矩形相加后,减去重叠部分(左上角矩形),最后加上当前点的值。
2.2 区域求和推导
给定任意矩形区域(x1,y1)到(x2,y2),其和可以通过前缀和数组快速计算:
cpp复制area_sum = sum[x2][y2] - sum[x1-1][y2] - sum[x2][y1-1] + sum[x1-1][y1-1]
这个推导过程同样基于容斥原理:用大矩形减去左侧和上方的矩形,再加回被重复减去的左上角矩形。
3. 激光炸弹问题解法实现
3.1 算法步骤详解
-
数据预处理:
- 读取所有目标点坐标和价值
- 构建二维数组存储每个格点的价值(注意坐标从1开始)
- 处理坐标重叠情况(同一格点可能有多个目标)
-
构建前缀和数组:
- 按照2.1节的公式逐行计算前缀和
- 边界处理:i=0或j=0时sum[i][j]=0
-
枚举所有可能的炸弹位置:
- 对于每个(i,j)作为炸弹右下角
- 计算炸弹
