第2题-双通道评测格网
小红书9月10日机考题目与解析
给定一张 行 列的评测格网。格子 上有两个通道分 与 。
从 走到 ,每次只能向右走到 或向下走到 ,不可越界。
路径上每个格子(含起终点)须把 与 分别记入主账户与对照账户,二者各得其一。
设主账户合计为 ,对照账户合计为 。求所有合法路径与分配方案下 的最小值。
输入描述
输入共 行。第一行两个整数 和 ;接下来 行每行 个整数,表示 ;再接下来 行每行 个整数,表示 。
数据范围:,。
输出描述
输出一行一个整数,即最小的 。
样例 1
输入:
2 2
4 1
2 5
2 3
6 1输出:
0说明:路径 。:主账户记 ,对照账户记 ;:主账户记 ,对照账户记 ;:主账户记 ,对照账户记 。此时 ,,。另一条路径 上, 至少为 ,更差。
思路
路径 DP + 可达集合(bitset)。每个格子的贡献是 (: 记主账户得 , 记主账户得 ),问题变成:路径上给每个 选符号,最小化总和的绝对值。
用 DP 维护「走到 时所有可达差值」的集合。路径长度 、数值 ,差值范围 ,把集合编码成一个大整数的位掩码(第 位为 1 表示可达),转移只需一次移位:
其中
cur = dp[i-1][j] | dp[i][j-1](向右/向下两来源合并)。Python
大整数位运算一次处理整个集合,复杂度约
(
为差值范围,
为机器字长),远快于逐值布尔 DP。
代码
n, m = map(int, input().split())
X = [list(map(int, input().split())) for _ in range(n)]
Y = [list(map(int, input().split())) for _ in range(n)]
L = n + m - 1
OFF = 80 * L + 1 # 差值偏移,覆盖最坏 ±80*L
dp = [[0] * m for _ in range(n)]
d00 = abs(X[0][0] - Y[0][0])
dp[0][0] = (1 << (OFF + d00)) | (1 << (OFF - d00))
for i in range(n):
for j in range(m):
if i == 0 and j == 0:
continue
cur = 0
if i > 0:
cur |= dp[i - 1][j]
if j > 0:
cur |= dp[i][j - 1]
e = abs(X[i][j] - Y[i][j])
dp[i][j] = (cur << e) | (cur >> e)
mask = dp[n - 1][m - 1]
k = 0
while not ((mask >> (OFF + k)) & 1) and not ((mask >> (OFF - k)) & 1):
k += 1
print(k)第2题-双通道评测格网
https://mingsm17518.github.io/2026/11/03/刷题笔记/机考/小红书/2026年9月10日/第2题-双通道评测格网/