【洛谷 P1902 】刺杀大使|二分答案 + DFS

一、题目分析

题意简述

迷宫是 n×m 的网格:

  • 第 1 行所有格子是入口,伤害值全为 0
  • 第 n 行每一格都有机关,必须全部走到
  • 除首尾两行外,房间有激光伤害 p[i][j]
  • 士兵路径上所有格子的伤害最大值为该士兵代价
  • 可以派出多名士兵,全队代价 = 所有士兵代价里的最大值
  • 求全队最小的最大伤害代价

核心考点拆解

  1. 最小值最大化模型:典型二分答案场景 —— 我们二分一个伤害上限 mid,验证是否存在方案:所有第 n 行机关都能通过伤害≤mid的路径从第 1 行入口抵达。

  2. 连通性校验:二分的判定函数用 DFS/BFS,只走伤害≤当前二分值的格子,看能否覆盖全部终点(第 n 行)。

  3. 网格搜索:四向移动,边界判断、访问标记防回头重复搜索。

解题思路总览(二分答案模板逻辑)

  1. 二分区间:伤害值域 [0, 1000],左边界 l=-1,右边界 r=1001
  2. 二分判定:给定限制值 mid,只允许走 p[i][j] ≤ mid 的格子,从第 1 行全部起点出发,看第 n 行所有单元格是否连通
  3. 二分收缩
    • 若能连通全部终点:说明 mid 可行,尝试更小值,r=mid
    • 若不能连通:限制太小,需要放大伤害,l=mid
  4. 最终结果:r 就是满足条件的最小最大伤害

二、算法原理详解

1. 二分答案为什么适用?

题目求「所有士兵路径伤害最大值的最小取值」,满足二分单调性:

  • 如果伤害上限 X 可行(能走完所有机关),那么所有大于 X 的数值一定可行
  • 如果 X 不可行,所有小于 X 的数值一定不可行

单调区间可以通过二分快速逼近最优解,把 "求最优值" 转化为 "给定值做连通性判断",时间复杂度大幅优化。

2. DFS 判定函数作用

给定伤害阈值 z,仅遍历网格中 p[x][y] ≤ z 的格子,标记可达区域。

判定逻辑:第 n 行所有单元格都被标记可达 → 阈值 z 合法。

3. 时间复杂度估算

  • 二分次数:值域 0~1000,最多二分 10 次
  • 单次 DFS:网格最多 1005×1005,单次遍历 O(nm)
  • 总复杂度:O(10 × n × m),对于 n,m≤1000 完全通过,不会超时

三、完整可 AC 修正代码

#include <bits/stdc++.h>
using namespace std;
const int N =  1005;
int dx[] = {0,0,1,-1};
int dy[] = {1,-1,0,0};
int n,m,p[N][N];
bool vis[N][N];
bool dfs(int x,int y, int z){
	if(x==n) return true;
	vis[x][y] = true;
	for(int i=0; i<4; i++){
		int newx = x+dx[i];
		int newy = y+dy[i];
		if(newx>=1 && newx<=n&&newy>=1&&newy<=m&&!vis[newx][newy]&&p[newx][newy]<=z)
			if(dfs(newx,newy,z)) return true;
	}
	return false;
}
int find(){
	int l = -1, r = 1001;
	while(l+1<r){
		int mid = l+r>>1;
		memset(vis,0,sizeof vis);
		if(dfs(1,1,mid)) r = mid;
		else l = mid;
	}
	return r;
}
int main() {
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1; j<=m;j++){
			cin>>p[i][j];
		}
	}
	cout<<find();
	
	return 0;
}

四、样例推演(输入 #1)

输入样例:

4 2
0 0
3 5
2 4
0 0

网格伤害矩阵:

行1:0  0
行2:3  5
行3:2  4
行4:0  0

二分过程:

  1. mid=5:所有格子都能走,第 4 行全部连通,可行,记录 ans=5,缩小右边界
  2. mid=2:只能走伤害≤2 的格子,第二行 5、第三行 4 无法通行,第四行右列不可达,不可行
  3. mid=3:伤害上限 3,路径:
    • (1,1)→(2,1)(伤害 3)→(3,1)(伤害 2)→(4,1)
    • (1,2) 向下无法走 5,横向连通 (1,1) 绕左路到达第四行两格,全部机关覆盖

最终最小合法值为 3,和样例输出匹配。

五、总结

洛谷 P1902 "刺杀大使" 是一道经典的二分答案 + 连通性检验题目,主要考察:

  1. 二分答案思想:将最优化问题转化为判定问题
  2. 网格连通性:DFS/BFS 遍历可达区域
  3. 边界条件处理:注意起点是整行,终点也是整行
  4. 时间复杂度控制:二分 + 搜索的组合在合理范围内

掌握这道题后,可以举一反三解决类似的 "最小值最大化" 或 "最大值最小化" 问题,这类问题在算法竞赛中非常常见。

关键点:一定要从第 1 行的所有入口开始搜索,不能只从 (1,1) 开始,这是本题最容易出错的地方。

posted on 2026-06-22 09:41  5iCode  阅读(11)  评论(0)    收藏  举报

导航