迭代加深枚举单位分数个数,用剩余项上界和最优末分母剪枝。
OJ: luogu
题目 ID: P1763
难度:提高+/省选-
标签:迭代加深DFS分数python
日期: 2026-07-16 20:10
题意
把真分数表示成分母严格递增的单位分数和。项数越少越优;项数相同时,最大分母越小越优。
思路
按项数从 1 开始迭代加深,第一个有解的层数保证项数最少。剩余分数为 a/b 时,下一个分母至少为 ceil(b/a)。
若还剩 slots 项且下一分母为 x,所有后续单位分数都不超过 1/x,必须满足 slots/x >= a/b,由此得到枚举上界 slots*b//a。最后一项必须恰好等于剩余分数,可以直接判整除。
同一深度记录最大分母最小的方案。
Python 知识
math.gcd每步约分,避免分子分母无谓膨胀。- 海象运算符在循环条件中同时取得当前深度搜索结果。
path.append/pop原地维护当前分母序列。
代码
python
import math
numerator, denominator = map(int, input().split())
path = []
def find(term_count):
best = None
def dfs(depth, start, a, b):
nonlocal best
slots = term_count - depth
if slots == 1:
if b % a:
return
value = b // a
if value < start or value > 10**7:
return
candidate = path + [value]
if best is None or candidate[-1] < best[-1]:
best = candidate
return
lower = max(start, (b + a - 1) // a)
upper = min(10**7, slots * b // a)
if best is not None:
upper = min(upper, best[-1] - 1)
for value in range(lower, upper + 1):
next_a = a * value - b
if next_a <= 0:
continue
next_b = b * value
divisor = math.gcd(next_a, next_b)
path.append(value)
dfs(depth + 1, value + 1, next_a // divisor, next_b // divisor)
path.pop()
dfs(0, 2, numerator, denominator)
return best
terms = 1
while (answer := find(terms)) is None:
terms += 1
print(*answer)复杂度
搜索复杂度取决于最优项数与分母范围,最坏指数级;递归空间等于答案项数。
总结
题目按“项数优先”排序答案时,IDDFS 自然匹配第一关键字,再在同层比较第二关键字。