我需要使用数字1和2找到一个总和(比如说1000000)的方法数量。顺序很重要。我使用组合制作了一个解决方案:
其中n
是总和。
示例:
对于n=7
,有21
种方法。
1111111,111112,111121,111211,112111,121111,2111111,12122 .... 1222,2122,2212,2221
这个数字可能非常大,我必须找到一些大的素数模数。 (是的,它是在线编码竞赛的一个小问题)。 我需要一个更加电脑友好的配方..请帮忙吗? 或者可以通过创建递归和矩阵求幂来完成它?
答案 0 :(得分:1)
这样做的方式数等于第n个Fibonacci数,F(n),易于计算。
通过归纳证明。假设n为真。考虑一个长度为n + 1的序列。这可以通过将总n或2的序列加1到总n-1的序列来形成。这是不同的,代表了所有可能性。
所以F(n + 1)= F(n)+ F(n-1) F(1)= 1
干净,呵呵?
答案 1 :(得分:1)
您要查找的数字是第n个斐波纳契数。
最好的方法(因为你说n可能非常大)是实现这个递归O(log n)
公式(这些是2x2矩阵,对于丑陋的格式感到遗憾)。
[F(n+2)] = [1 1] [F(k+1)]
[F(n+1)] [1 0] [F (k) ]
也许明确的形式会更适合你,而不是递归的形式:
[1 1]^n = [F(k+1) F(k) ]
[1 0] [ F(k) F(k-1)]
这是我所知道的计算斐波纳契数的最快方法。 请记住,输出增长非常快,因此您无法缓存大n的结果。
答案 2 :(得分:0)
以下是我提出的建议:
def onesAndTwos(num):
if num <= 0:
return set()
elif num == 1:
return set([(1, 0)])
elif num == 2:
return set([(2,0), (0, 1)])
else:
setA = set([(1 + x[0], x[1]) for x in onesAndTwos(num-1)])
setB = set([(x[0], 1 + x[1]) for x in onesAndTwos(num-2)])
setA.update(setB);
return setA
print onesAndTwos(10)
print len(onesAndTwos(10))
它使用一组元组,其中第一个元素是一个元素,第二个元素是二元组的数量。因此可以使用set[(3,0), (1,1)]
生成3的总和。要查找有多少组合,您可以计算集合中的元组。输出为10:
set([(8, 1), (6, 2), (0, 5), (4, 3), (10, 0), (2, 4)])
6
这有点像动态编程方法,我们在整个过程中都有一组重复的子问题和类似的结构,这使我们能够在之前的解决方案的基础上进行构建。这不是最佳的,因为你没有在两个分支中重复使用先前计算的值(第一个拿走1时,第二个拿走2时),所以我认为这是一个天真的解决方案。
答案 3 :(得分:0)
public class Fibonacci {
public static int magic(int input) {
if (input == 1) {
return 1;
} else if (input == 2) {
return 2;
} else {
return magic(input-1) + magic(input-2);
}
}
public static void main(String args[]) {
int input = 7;
int numberOfCombinations = magic(input);
System.out.println("The total number of combinations for the given integer "+input+" is "+numberOfCombinations);
}
}
完整且可正常运行的Java代码。随意使用它为您的比赛。我希望代码对底层算法不言自明。祝你好运!