LC 3348. 最小可整除数位乘积 II
https://leetcode.cn/problems/smallest-divisible-digit-product-ii/description/
这题看了题解,主要的障碍在于怎么应对如果需要更长的字符串。如果是相同长度的字符串的话,那么使用数位DP就行。这里的数位DP其实缓存的不是最终结果,缓存的是哪些不可行的结果。因为我们是按照顺序来搜索的,所以如果一旦找到正确的结果就可以返回。
为了应对“需要更长的字符串”这种情况,可以针对num进行对齐。假设t包含x个因子的话,那么长度x的字符串肯定是满足条件的。假设t可以分解为3个2和2个5,那么'22255' 是肯定满足条件的。我们按照这个长度对num进行补齐就行。对于补齐的部分可以先看看'0'是否满足,如果不满足的话在尝试之后的结果。
class Solution: def smallestNumber(self, num: str, t: int) -> str: cnt = 0 t2 = t for p in (2, 3, 5, 7): while t2 % p == 0: t2 = t2 // p cnt += 1 if t2 != 1: return "-1" pad = max(cnt - len(num), 0) + 1 num = '0' * pad + num def gcd(a, b): while b != 0: a, b = b, a % b return a ans = [0] * len(num) import functools @functools.lru_cache(None) def dfs(i, t, cap): if i == len(num): # print(ans, t) return t == 1 if i < pad and not cap: if dfs(i + 1, t, cap): return True d = int(num[i]) low = d if not cap else 0 for x in range(max(low, 1), 10): ans[i] = x if dfs(i + 1, t // gcd(t, x), cap or (x > d)): return True return False dfs(0, t, False) dfs.cache_clear() ans = ''.join([str(x) for x in ans]) # print(ans) return ans.lstrip('0')