algorithm - 搜索函数返回特定值的输入

时间:2014-12-05 07:18:33

标签: algorithm function

我有以下功能:

F(0) = 0
F(1) = 1
F(2) = 2
F(2*n) = F(n) + F(n+1) + n , n > 1
F(2*n+1) = F(n-1) + F(n) + 1, n >= 1

我收到了一个n < 10^25号码,我必须证明其存在a,例如F(a)=n。由于函数的定义方式,可能存在n,例如F(a)=F(b)=n where a < b,在这种情况下,我必须返回b而不是a

到目前为止我所拥有的是:

  • 我们可以将这个函数分成两个严格的单调系列,一个用于F(2 * n),一个用于F(2 * n + 1),并且可以在对数时间内找到指定的值,所以这个发现或多或少完成。
  • 我还发现F(2*n) >= F(2*n+1) for any n,所以我首先在F(2 * n)中搜索它,如果我在那里找不到它,我搜索F(2 * n + 1)< / LI>
  • 问题在于计算函数值。即使有一些高达10 ^ 7的疯狂记忆然后又回落到递归,它仍然无法在合理的时间内计算出10 ^ 12以上的值。

我认为我有实际找到我需要的算法,但是我无法足够快地计算F(n)。

1 个答案:

答案 0 :(得分:4)

只需使用记忆一直到目标值,例如在Python中:

class Memoize:
    def __init__(self, fn):
        self.fn = fn
        self.memo = {}
    def __call__(self, *args):
        if not self.memo.has_key(args):
            self.memo[args] = self.fn(*args)
        return self.memo[args]

@Memoize
def R(n):
    if n<=1: return 1
    if n==2: return 2
    n,rem = divmod(n,2)
    if rem:
        return R(n)+R(n-1)+1
    return R(n)+R(n+1)+n

这会立即计算10 ** 25的答案。

这有效的原因是因为递归的性质意味着对于二进制数abcdef,它最多只需要使用这些值:

abcdef
abcde-1,abcde,abcde+1
abcd-2,abcd-1,abcd,abcd+1,abcd+2
abc-2,abc-1,abc,abc+1,abc+2
ab-2,ab-1,ab,ab+1,ab+2
a-2,a-1,a,a+1,a+2

在每一步中你可以向上或向下移动1,但你也可以将数字除以2,这样你离开原始数字的最多就是有限的。

因此,备忘录代码最多只能使用5 * log_2(n)个评估。