📅  最后修改于: 2023-12-03 15:07:26.827000             🧑  作者: Mango
给定一个最多由0和7组成的N位数字集,求该集合中能够构成的最大可以被50整除的数。
为了方便讲解,当成人数、重量每一个物品都是1处理(正常是与该物品转换后的数值相同),考虑一下0/7两个数字在构成能否被50整除具有互补性,以及N较大的时间复杂度,容易想到使用动态规划求解。
定义状态 $f(i,j)$ 表示用前 $i$ 个数字,且模 50 余数为 $j$ 时的最大位数。
对于每一个状态 $f(i,j)$ ,存在以下两种转移情况:
最后从大到小枚举位数,直接输出最终的方案即可得到答案。
def solution(n: str) -> str:
n = [int(x) for x in n]
f = [[-int(1e9)] * 50 for _ in range(len(n) + 1)]
f[0][0] = 0
for i in range(1, len(n) + 1):
for j in range(50):
f[i][j] = max(f[i][j], f[i - 1][j])
f[i][(10 * j + n[i - 1]) % 50] = max(f[i][(10 * j + n[i - 1]) % 50], f[i - 1][j] + 1)
if f[len(n)][0] <= 0:
return 'no solution'
ans = []
j = 0
for i in range(len(n), 0, -1):
if j == 0 and f[i][j] > f[i - 1][j]:
ans.append(str(n[i - 1]))
j = (j - n[i - 1] * pow(10, f[i - 1][j] - 1, 50)) % 50
return ''.join(ans[::-1])
状态数 $O(n\times50)$,转移时间为 $O(1)$,因此总复杂度 $O(n^2)$。