[Codewars]-Explosive Sum
题目:
- 翻译成中文是整数分拆
- 简单说:一个整数可以分拆若干个整数之和,问这种组合有多少种?
- 举个例子:整数4,可以是
1+1+1+1, 1+1+2, 1+3, 2+2, 4
共5种,故应该返回5.
思路:
- 思路可以参考百度:整数分拆
- 我简单解释下:
- 把一个整数分割成若干个不大于m的整数的和,符合以下规律
- 这样思路就很清晰了,直接用递归就可以了
- 但是(这个但是很重要),
- 细心观察你会发现用递归法,其中重复计算了很多个数。
- 比如:计算
f(10,10)
f(10,10) = 1+f(10,9)
= 1+f(10,8)+f(1,9)
= 1+f(10,7)+f(2,8)+f(1,9)
= 1+f(10,7)+f(2,2)+f(1,1)
= 1+f(10,7)+ [ 1+f(2,1) ] +f(1,1)
= 1+f(10,7)+ [ 1+f(2,0)+f(1,1) ] +f(1,1)
= ...
- 可以发现f(1,1)已经计算了两次了,程序继续执行还会更多地重复
- 动态规划方法就是为了解决重复的步骤而生的。
- 具体方法看下面代码
解答:
function GetPartitionCount(n,m){
if (n == 1 || max == 1)return 1;
if (n < max)return (GetPartitionCount(n, n)) ;
if (n == max)return (1 + GetPartitionCount(n, n - 1)) ;
else return (GetPartitionCount(n - max, max) + GetPartitionCount(n, max - 1));
}
function sum(num) {
if(num<=0){return 0}
var ww = []
for(var i = 1 ; i <= num ; i ++ ){
ww[i] = []
for(var j=1 ; j <=i ; j ++){
if(j==1||i==1){
ww[i][j] = 1
}else{
if(i==j){
ww[i][j] = ww[i][j-1]+1
}else if( (i-j)<j ){
ww[i][j] = ww[i-j][i-j] + ww[i][j-1]
}else{
ww[i][j] = ww[i-j][j]+ ww[i][j-1]
}
}
}
}
return ww[num][num]
}