LC 8013. 范围中美丽整数的数目
https://leetcode.cn/problems/number-of-beautiful-integers-in-the-range/description/
这次算是自己琢磨出来怎么写数位dp的,实现中有两个点,分别都是和isStart有关系的:
- 只有isStart=False,的时候,才可以继续以isStart=False递归下去,否则就要开始枚举具体数字了。
- 只有isStart=True的时候,才能枚举left被用于odd/even. 如果isStart=False,那么只能粗略判断(odd + left) < even
然后就是这个状态中value必须取模k, 否则这个状态数量就太大了。
class Solution: def numberOfBeautifulIntegers(self, low: int, high: int, k: int) -> int: def OkOddEven(isStart, odd, even, left): if isStart: for x in range(0, left + 1): if (odd + x) == (even + left - x): return True return False else: if (odd + left) < even or (even + left) < odd: return False return True def search(ss): import functools @functools.cache def f(i, isLimit, isStart, odd, even, value): # print(i, isLimit, isStart, odd, even, value) if i == len(ss): if not isStart: return 0 if odd == even and value % k == 0: # print(value) return 1 return 0 left = len(ss) - i if not OkOddEven(isStart, odd, even, left): return 0 ans = 0 if not isStart: ans += f(i + 1, True, False, odd, even, value) from_value = 1 if not isStart else 0 to_value = int(ss[i]) if not isLimit else 9 for x in range(from_value, to_value + 1): ans += f(i + 1, isLimit or x < int(ss[i]), isStart or x != 0, odd + (x % 2), even + (x + 1) % 2, # value * 10 + x) (value * 10 + x) % k) return ans return f(0, False, False, 0, 0, 0) h = search(str(high)) l = search(str(low - 1)) ans = h - l return ans