我正在尝试做项目欧拉数219,但我没有掌握它。我正在尝试使用Python,根据项目Euler应该能够在一分钟内完成它!这让我觉得他们不可能想要我计算每个单独的位串,因为在Python中它会太慢 - 必须有一个子O(n)算法。
我已经看过一个递归解决方案,它存储了位串可能的前缀,以便它可以快速选择一个新的位串,甚至可以将它们分组考虑。这仅适用于超过10的强制值:
cost(1) = 1
cost(2) = 5
cost(3) = 11
cost(4) = 18
cost(5) = 26
cost(6) = 35
cost(7) = 44
cost(8) = 54
cost(9) = 64
cost(10)= 74
cost(11)= 85
cost(12)= 96
过去这个,我正在努力理解如何减少问题。始终可以创建类似于以下的模式:
1
01
001
0001
00001
00000
但对于7位以上的字符串来说,这不是最佳选择。任何人都可以指导我应该考虑的事情吗?
答案 0 :(得分:8)
蛮力不是正确的做法。这是其中一个问题,如果你知道某件事情,那并不难,但如果你从未听说过这件事,那实际上是不可能的。那件事是Huffman trees。
[编辑]进一步审查后,似乎你无法在具有特定频率的N个节点上构建一个霍夫曼树,因为字符串的成本函数是4 *(#of 1's)+(#of 0's) 。如果cost函数是字符串的长度(或其倍数),那么你可以创建一个Huffman树。
任何无前缀的代码集都可以表示为类似霍夫曼的二叉树,其中每个节点都有0或2个子节点,叶节点代表代码。给定具有N个节点的树,我们可以构造具有N + 1个节点的树,如下所示:
因此,如果节点的代码先前是xxxx,那么我们从代码集中删除该代码(因为它不再是叶子),并添加两个代码xxxx0和xxxx1。
现在增加了代码集的总成本`cost(xxxx0)+ cost(xxxx1) - cost(xxxx)= cost(0)+ cost(1)+ cost(xxxx)= 5 + cost(xxxx)
因此,mincost(N + 1)<= mincost(N)+ 5 +成本(N的最佳解决方案中最便宜的代码)。我的理论是,不平等应该是平等的,但我还没有能够证明它。对于您列出的所有强制强制的值,此陈述实际上是相等的。
如果它是平等的,那么要解决问题,你会做的是:
如果您使用priority queue,则应该能够在O(N log N)时间内执行此操作。考虑到10 9 的上限,这可能是可行的,也可能是不可行的。
答案 1 :(得分:1)
Adam:感谢加载链接 - 看起来非常很有希望!在阅读维基百科文章后,我不确定的是如何考虑系数4。我正在努力将Project Euler问题“映射”到算法中。字母表必须长10 ^ 9项,但重量是多少?
困扰我的另一件事是,霍夫曼编码充其量O(n)肯定太慢了,就像我上面提到的那样......
mattiast:我不认为你的复发是有效的(或者我误解了它!)。我对它的解释是:
def cost(n):
if n == 1: return 1
m = None
for k in range(1, n):
v = cost(k)+cost(n-k)+k+4*(n-k)
if not m or v < m: m = v
return m
print(cost(6))
当它应该是35时,它返回的值是41.所有相同的,如果我的值是正确的,那么我找不到ATT的整数序列百科全书中的差异。
答案 2 :(得分:1)
N = 10 ** 9
t = [0]
for x in xrange(N): m = min(t) t.remove(M) t.append(M + 1) t.append(M + 4) print sum(t),t
答案 3 :(得分:0)
我如何解决它,计算成本(n)高达n = 1000,然后只是猜测它是如何从那里开始的。如果你看一下连续值的差异,并使用The encyclopedia of integer sequences(和一些想象力),你可以猜出规则。
您可以使用重复Cost(n) = min {Cost(k)+Cost(n-k)+k+4*(n-k) | 0 < k < n}
计算带有一种动态编程的小(&lt; = 1000)示例。
答案 4 :(得分:0)
Adam Rosenfield的解决方案看起来非常有效。现在已经很晚了(大约午夜!)所以我会离开它直到凌晨。我在C中有一个高效的优先级队列实现,所以明天我将尝试使用它并找到解决方案。
我将报告算法的成功,但推理对我来说似乎是合理的,并且它与数据密切相关(如上所述)。但是,正如我一直在喃喃自语,必须有一个子O(n)算法! ; - )
答案 5 :(得分:0)
事实证明,O [n * log(n)]不是太慢,但是大致为O(n)的存储器复杂度是。然而,上面提出的算法可以进一步降低到O(n)时间复杂度和低存储器复杂度。要做到这一点,可以使用数组x,其中x [a] =成本a的数值的数量。
所做出的假设给出了10 ^ 9的正确结果,所以我认为它们是正确的。