【发布时间】:2014-10-24 02:24:06
【问题描述】:
我正在尝试计算范围 A 到 B 之间的整数和 S(假设 S=60)。
A 和 B 的范围从 1 到 10^18。
让 X 是一个数字,直到 Y 我们必须计算整数。
X = x1 x2 ... xn - 1 xn 和 Y = y1 y2 ... yn - 1 yn,其中 xi 和 yi 是 X 和 Y 的十进制数字。
leftmost_lo 作为 xi yi,否则为 n + 1。
函数计数返回具有属性 X ≤ Y 且 X 的数字总和为 60 的整数 X 的数量 f(Y)。
根据上述定义,设 n 为 Y 的位数,y[i] 为 Y 的第 i 个十进制数字。下面的递归算法解决了这个问题:
count(i, sum_so_far, leftmost_lo, leftmost_hi):
if i == n + 1:
# base case of the recursion, we have recursed beyond the last digit
# now we check whether the number X we built is a valid solution
if sum_so_far == 60 and leftmost_lo <= leftmost_hi:
return 1
else:
return 0
result = 0
# we need to decide which digit to use for x[i]
for d := 0 to 9
leftmost_lo' = leftmost_lo
leftmost_hi' = leftmost_hi
if d < y[i] and i < leftmost_lo': leftmost_lo' = i
if d > y[i] and i < leftmost_hi': leftmost_hi' = i
result += count(i + 1, sum_so_far + d, leftmost_lo', leftmost_hi')
return result
Compute the number f(Y) of integers X with the property X ≤ Y and X has the digit sum 60
现在我们有了 f(Y) = count(1, 0, n + 1, n + 1) 并且我们已经解决了问题。运行时
对于这个特定的实现来说是 O(n^4)。
我从这个链接了解这个概念。 How to count integers between large A and B with a certain property?
但无法理解如何优化。
现在如何针对这个特定问题将其优化为 O(n) 解决方案。
谁能帮帮我。
【问题讨论】:
-
这些类型的计数问题通常通过应用数学和组合公式来解决,而不是实际评估每个可能的候选者。
-
为什么用C、C++标记?代码不是 C。
-
@user1990169,是的,你可以通过计算数学公式来解决这个问题,但我正在考虑解决这个问题的一般方法。
-
仅供参考 - 我为任意 A 和 B 添加了一个大纲想法,它可以适用于我的或 M Oehm 的方法。
标签: algorithm dynamic-programming