[Codewars]-Explosive Sum(递归法和动态规划法)

[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]
}

猜你喜欢

转载自blog.csdn.net/qq_41882147/article/details/79768971