依旧是codewars上面的题目,献上链接
codewars 爆炸总和
整数分区
整数n的分区是正整数(不一定是不同的)的无序集合,其加起来为n。这种分区的数量通常表示为p(n)。函数p称为分区函数,其值列表如下。这从p(0)= 1开始,因为只有一个正整数的集合,其总和为零(即空集合)。
n:p(n)
0:1
1:1 //1
2:2 //1+1 2
3:3 //1+1+1 1+2+1 3
4:5 //1+1+1+1 1+1+2 3+1 2+2 4
5:7 //1+1+1+1+1 1+1+1+2 1+1+3 1+2+2 4+1 2+3 5
6:11 //1+1+1+1+1+1 1+1+1+1+2 1+1+1+3 1+ 1+2+2 1+1+4 1+2+3 1+5 2+2+2 2+4 3+3 6
...
数学规律
在写代码之前应该先搞懂数学分区的数学规律。
假设将n进行分区,通过规律我们可以知道n各分区中包含n-1的分区加上1,整理之后得出以下规律:
p(n) = p(n-1)
+p(n-2) - p(n-2)中有“+1”的分区方法
+p(n-3) - p(n-3)中有“+1”的分区方法 - p(n-3)中有“+2”的分区方法
…
直到 n-i < i
p(n) | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
1 | 2 | 3 | 5 | 7 | 11 | 15 | 22 | 30 | 42 |
w[i][n] | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 规律 |
---|---|---|---|---|---|---|---|---|---|---|---|
+0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
+1 | 0 | 1 | 2 | 3 | 5 | 7 | 11 | 15 | 22 | 30 | p(n-1) |
+2 | 0 | 0 | 0 | 1 | 1 | 2 | 2 | 4 | 4 | 7 | w[i-1][n-1]-w[i-1][n-2] |
+3 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 2 | 2 | w[i-1][n-1]-w[i-1][n-3] |
+4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | w[i-1][n-1]-w[i-1][n-4] |
+5 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | w[i-1][n-1]-w[i-1][n-5] |
… | |||||||||||
+i | w[i-1][n-1]-w[i-1][n-i] |
则
p ( n ) = ∑ w [ i ] [ n ] ( 0 ≤ i ≤ ( n + 1