码迷,mamicode.com
首页 > 其他好文 > 详细

PARTITION(number theory) ALSO Explosive number in codewars

时间:2015-07-15 18:59:24      阅读:206      评论:0      收藏:0      [点我收藏+]

标签:

问题出于codewars,简言之:寻找和为一个整数的的不同整数组合。https://en.wikipedia.org/wiki/Partition_(number_theory) 

例如:和为6的整数组合有如下11种,

6

5 + 1

4 + 2

4 + 1 + 1

3 + 3

3 + 2 + 1

3 + 1 + 1 + 1

2 + 2 + 2

2 + 2 + 1 + 1

2 + 1 + 1 + 1 + 1 + 1

1 + 1 + 1 + 1 + 1 + 1

解法一:

为了避免重复,我们可以选择逐渐递减第一个加数,直到不小于n的一半(保持分解的数字),然后对第一个加数应用这个策略,还是以6为例:

6

5 + 1

4 + 2

3 + 3

然后对第一个加数5应用这个策略,

4 + 1

3 + 2

接着对分解4和3应用这一策略,得到如下:

6

5 + 1

 4 + 1 + 1

  3 + 1 + 1 + 1

   2 + 1 + 1 + 1 + 1 

    1 + 1 + 1 + 1 + 1 + 1

  2 + 2 + 1 + 1

 3 + 2 + 1

4 + 2

  2 + 2 + 2

3 + 3

因为我们已经有了3+2+1,对于4而言就不在分解成3+1+2,此处的限制条件分解4不能产生比2(4后面的2)小的数字,所以只能是2+2,同理,3就不再分解了,因为分解不出比3(后面那个)还大的数了。

技术分享
 1 def exp_sum(n):
 2     if n < 0:
 3         return 0
 4     if n == 0:
 5         return 1
 6     return help(n, 1)
 7 
 8 def help(n, mini):
 9     tmp = 1
10     if n <= 1:
11         return 1
12     for i in range(1, n/2+1):##保证n-i不小于i
13         if i >= mini: ##保证分解得到的数不小于后面的较小的数
14             tmp = tmp + help(n-i, i)
15     return tmp
16 print exp_sum(6)
View Code

当然了,这个递归的速度是很慢的,T(n) = T(n-1) + T(n-2) +...+ T(ceil(n/2)),时间复杂度是指数级别的。

解法二:

可以开辟一个大小为n的list存储已经计算的结果:

技术分享
 1 def exp_sum(n):
 2     if n < 0:
 3         return 0
 4     if n == 0 or n == 1:
 5         return 1
 6     solution = [1] + [0]*n
 7 
 8     for i in range(1, n):
 9         for j in range(i, n+1):
10             solution[j] += solution[j-i] 
11     return solution[n]+1
View Code

解法三:

根据维基百科上的generation function:p(k) = p(k − 1) + p(k − 2) − p(k − 5) − p(k − 7) + p(k − 12) + p(k − 15) − p(k − 22) − ... + (-1)^(k+1)*p(k − (3k^2 - k)/2) + (-1)^(k+1)*p(k − (3k^2 + k)/2)

技术分享
 1 def exp_sum(n):
 2     solutions = [1]*(n + 1)
 3 
 4     for i in xrange(1, n + 1):
 5         j, k, s = 1, 1, 0
 6         while j > 0:
 7                 j = i - (3 * k * k + k) / 2
 8                 if j >= 0:
 9                         s += (-1) ** (k+1) * solutions[j]
10                 j = i - (3 * k * k - k) / 2
11                 if j >= 0:
12                         s += (-1) ** (k+1) * solutions[j]
13                 k += 1
14         solutions[i] = s
15 
16     return solutions[n]
View Code

参考链接:

  https://en.wikipedia.org/wiki/Partition_(number_theory)

  http://stackoverflow.com/questions/438540/projecteuler-sum-combinations

                        2015-07-15 17:03:25

PARTITION(number theory) ALSO Explosive number in codewars

标签:

原文地址:http://www.cnblogs.com/FARAMIR/p/4648905.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!