问题出于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(后面那个)还大的数了。

 def exp_sum(n):
     if n < 0:
         return 0
     if n == 0:
         return 1
     return help(n, 1)

 def help(n, mini):
     tmp = 1
     if n <= 1:
         return 1
     for i in range(1, n/2+1):##保证n-i不小于i
         if i >= mini: ##保证分解得到的数不小于后面的较小的数
             tmp = tmp + help(n-i, i)
     return tmp
 print exp_sum(6)

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

解法二:

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

 def exp_sum(n):
     if n < 0:
         return 0
     if n == 0 or n == 1:
         return 1
     solution = [1] + [0]*n

     for i in range(1, n):
         for j in range(i, n+1):
             solution[j] += solution[j-i]
     return solution[n]+1

解法三:

根据维基百科上的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)

 def exp_sum(n):
     solutions = [1]*(n + 1)

     for i in xrange(1, n + 1):
         j, k, s = 1, 1, 0
         while j > 0:
                 j = i - (3 * k * k + k) / 2
                 if j >= 0:
                         s += (-1) ** (k+1) * solutions[j]
                 j = i - (3 * k * k - k) / 2
                 if j >= 0:
                         s += (-1) ** (k+1) * solutions[j]
                 k += 1
         solutions[i] = s

     return solutions[n]

参考链接:

  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的更多相关文章

  1. 2016级算法第二次上机-F.ModricWang's Number Theory II

    891 ModricWang's Number Theory II 思路 使得序列的最大公约数不为1,就是大于等于2,就是找到一个大于等于2的数,它能够整除序列中的所有数. 考虑使得一个数d整除数组中 ...

  2. 【BZOJ4026】dC Loves Number Theory 分解质因数+主席树

    [BZOJ4026]dC Loves Number Theory Description  dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯竭的水题资源.    给 ...

  3. BZOJ_4026_dC Loves Number Theory _主席树+欧拉函数

    BZOJ_4026_dC Loves Number Theory _主席树+欧拉函数 Description  dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯 竭 ...

  4. Number Theory Problem(The 2016 ACM-ICPC Asia China-Final Contest 找规律)

    题目: Mr. Panda is one of the top specialists on number theory all over the world. Now Mr. Panda is in ...

  5. [E. Ehab's REAL Number Theory Problem](https://codeforces.com/contest/1325/problem/E) 数论+图论 求最小环

    E. Ehab's REAL Number Theory Problem 数论+图论 求最小环 题目大意: 给你一个n大小的数列,数列里的每一个元素满足以下要求: 数据范围是:\(1<=a_i& ...

  6. 题解-Ehab's REAL Number Theory Problem

    Ehab's REAL Number Theory Problem 前置知识 质数 分解质因数 无向无权图最小环<讲> Ehab's REAL Number Theory Problem/ ...

  7. [Javascript] Use Number() to convert to Number if possilbe

    Use map() and Number() to convert to number if possilbe or NaN. var str = ["1","1.23& ...

  8. Ugly Number,Ugly Number II,Super Ugly Number

    一.Ugly Number Write a program to check whether a given number is an ugly number. Ugly numbers are po ...

  9. leetcode 263. Ugly Number 、264. Ugly Number II 、313. Super Ugly Number 、204. Count Primes

    263. Ugly Number 注意:1.小于等于0都不属于丑数 2.while循环的判断不是num >= 0, 而是能被2 .3.5整除,即能被整除才去除这些数 class Solution ...

随机推荐

  1. 简单实现div+css页面自适应

    Step1.在<head>添加如下代码<meta name="viewport" content="width=device-width, initia ...

  2. WCF方式调用asmx设置cookie

    以前旧的方式去调用web service, 可以通过CookieContainer去设置cookie,改用WCF方式去调用,则必须配置allowCookies属性为true <system.se ...

  3. C#中equals方法和==的区别

    Msdn中对equals方法的解释是:确定指定的对象是否等于当前对象. Equals方法是比较对象的内容,而==则是比较整个对象是否相等. Equals方法判断的是堆中的值,而==则判断的是堆栈中的值 ...

  4. 从远程oracle上导入到本地同一张表中不存在的记录的方法

    场景:在远程oracle上存在一张表A,在本地同样存在一张相同表结构的表B.由于本地表B中保存了业务系统操作产生的几条记录,同时原来导入了A中的部分记录,但是并没有保存A中全部的记录.A中有15条记录 ...

  5. oracle数据块的大小

    标准数据块用于临时表空间和系统表空间,同时也是一个表空间数据块的默认值.标准数据块的大小是在创建数据库时由参数DB_BLOCK_SIZE确定的.若要改变这一设置必须重建数据库. DB_CACHE_SI ...

  6. 使用SelectClipRgn注意事项

    SelectClipRgn 函数功能:该函数选择一个区域作为指定设备环境的当前剪切区域. 函数原型:int SelectClipRgn(HDc hdc, HRGN hrgn): 参数: hdc:设备环 ...

  7. DIV周边添加投影及背景固定

    DIV周边添加投影.tou{ width:1000px; height:300px; border:0px solid #999; background:#FFF; margin:0 auto; ma ...

  8. Linux install Maven3

    1. Download JDK1.6 http://www.oracle.com/technetwork/java/javase/downloads/jdk-6u31-download-1501634 ...

  9. Java Thread 总结

    目  录   线程的概述(Introduction) 线程的定义(Defining) 1) 继承java.lang.Thread类 2) 实现java.lang.Runnable接口 线程的启动(St ...

  10. 为TL-WR720N编译带mentohust和njit-client的openwrt固件

    openwrt的trunk版已经支持720N了.简单好多. 首先下载openwrt源码,我下的是trunk版 svn co svn://svn.openwrt.org/openwrt/trunk/ 然 ...