计算总和N的方法

时间:2014-08-30 16:30:50

标签: algorithm

对于任何非负整数K,假设我们正好有两个值为2 ^ K的硬币(即2的K次幂)。

现在我们给了一个很长的N.我们需要找到不同方式的数量,我们可以用我们拥有的硬币来表示N值。

(如果在表示中出现不同次数的值,则认为两个表示不同。)

示例:设N = 6然后回答为3,因为在这种情况下可能有以下三种表示形式:

{1, 1, 2, 2}
{1, 1, 4} and 
{2, 4}

如果N可以达到10 ^ 18,该如何做?

1 个答案:

答案 0 :(得分:0)

我们可以从简单的解决方案开始,我们有一个2,其余1。这当然要求N至少为3.否则,没有解决方案:

coins1 = N - 2
coins2 = 1
nSolutions = 1

让我们首先讨论找到M等硬币的可能合并操作的数量的任务,其中必须合并每个硬币(即,仅使用单个硬币类型)。这是M2的可能整数除法数。此过程可以缓存中间结果以更快地执行后续调用(请参阅动态编程)。

但这有用吗?在当前状态下,我们现在可以随后为一个1's交换两个2。这可以完成,直到不再有两个1's,总共floor(N/2 - 1)次。在每次合并之后(实际上在每次合并之后就足够了),我们必须检查所有2's可以合并的频率。该州仍有1's,因此我们无法使用其他类型的硬币:

while(coins1 >= 3)
{
    coins1 -= 2;
    coins2 += 1;
    nSolutions += 1;
    nSolutions += findNumberOfMerges(coins2); //this could be improved
}

如果剩下while,则剩下一个或两个1's。如果剩下一个,我们就完成了,因为这个必须始终存在,我们已经检查了所有可能的组合,以不同的方式表示2's

if(coins1 == 1)
    return nSolutions;

在另一种情况下,我们可以再次合并。但是,这不会导致有效状态,因为没有第二种硬币类型。但我们可以再次合并以获得有效状态(一个4(变为coins2),其余2's(变为coins1)):

coins1 = coins2 + 1 - 2;
coins2 = 1;
nSolutions += 1;

现在我们的状态与开头类似,因此我们可以再次运行整个过程。并且一次又一次,直到它返回。