我最近解决了河内塔问题。我用“分而治之”策略来解决这个问题。我将主要问题分成了三个较小的子问题,因此产生了重复发生。
T(N)= 2T(N-1)+1
解决这个问题导致
O(2 ^ n)[指数时间]
然后我尝试使用memoization技术来解决它,但是这里空间复杂度也是指数级的,并且堆空间很快耗尽,并且对于较大的n,问题仍然是无法解决的。
有没有办法在不到指数时间内解决问题?什么是解决问题的最佳时间?
答案 0 :(得分:11)
您可以解决重复问题并获得封闭表格。
T(n)= 2 * T(n-1)+ 1
T(n)= 2 *(2 * T(n-2)+ 1)+ 1
T(n)=(2 ^ 2)* T(n-2)+ 2 ^ 1 + 2 ^ 0
T(n)=(2 ^ k)* T(n-k)+ 2 ^(k-1)+ 2 ^(k-2)+ ... + 2 ^ 0
解决这个关闭来自
T(n)=(2 ^ n)-1,T(0)= 0
现在通过平方来使用取幂。
答案 1 :(得分:10)
这取决于“解决”的意思。具有3个钉子和n
磁盘的河内塔问题需要2**n - 1
个移动才能解决,所以如果你想要枚举这些移动,那么从枚举{你明显不能比O(2**n)
做得更好{1}}事情是k
。
另一方面,如果您只想知道所需的移动次数(不计算它们),计算O(k)
的操作要快得多。
另外值得注意的是,可以使用2**n - 1
空间复杂度迭代地完成移动的枚举,如下所示(O(n)
是最小的磁盘):
disk1
答案 2 :(得分:3)
不幸的是,在更短的时间内解决这个问题是不可能的,因为改变所有河内塔位置所需的移动次数是指数级的。 所以最好的解决方案是根据步骤数O(T)线性,所以尾数的解是指数O(2 ^ n)
答案 3 :(得分:0)
正好有2 ^ n-1个动作,所以为了列出它们,我们不能比O(2 ^ n)时间复杂度做得更好。
在O(1)中可以枚举必要的移动(如果采用任意大小的整数,则为O(log n))空间:
(define (fbs n i) (if (even? n) (fbs (/ n 2) (+ i 1)) i))
(define (fb n) (fbs n 1))
(define (hanois n i m)
(
cond
((= i m) "DONE")
(else
(define k (fb i))
(print "move disk " k " " (if (even? (+ n k)) "left" "right"))
(hanois n (+ 1 i) m))))
(define (hanoi n) (hanois n 1 (expt 2 n)))
[方程式]
请注意,此算法由于算术而具有log n的开销(并且算法fb
找到最低有效位集的位置)。涉及计数器上任何类型的递增/递减的任何天真解决方案都将具有相同的开销。
答案 4 :(得分:0)
这取决于你接受什么样的表示。想象一下 以下代表:
OneMove
from : integral
to : integral
Solution
step_one : optional reference to Solution
step_two : OneMove
step_three : optional reference to Solution
这样的表示实际上可以以线性复杂度创建,因为 有很多重复。
我刚尝试过,为64号高度构建了这样的解决方案 不到一毫秒。当然,踩过它仍然需要 2 n -1步。
您没有指定语言,但如果您想在C ++中使用代码,请删除一行。