母函数应用之整数分解

最近抽了点时间,把在 codewars 上切的题目整理了下,solutions 同步在了 Github。虽然没啥人看,也算给自己留个纪念吧。

今天要讲的是母函数的应用之整数分解方案数,关于母函数的解释可以自行谷歌百度,因为我觉得,即使不知道母函数的概念,也可以把代码看懂。

先来看这道题:How many ways can you make the sum of a number?

题意很简单,把一个整数拆分开来,有多少种分法,比如 4 就有 5 种:

4
3 + 1
2 + 2
2 + 1 + 1
1 + 1 + 1 + 1

思路是这样的,1-4 四个数字一个一个地拿出来,去求拼成 4 的方案数量。先定义一个数组 a,a[1] 表示拼成 1 的方案数,a[2] 表示拼成 2 的方案数,依次类推。初始时只有 a[0] 为 1,其他都为 0。

先拿出 1 来拼,显然 a[0]-a[4] 均为 1。

再拿出 2 来拼,这时的 a[4] 就可以从 a[2] 得到了,比方说我之前 a[2] 有 N 种,然后 a[4] 又能从 a[2] 加上个 2 拼成,那么 a[4] 的方案数量就得加上 a[2] 的数量了,如果有 a[6],那么 a[6] 也得加上 a[2] 的数量,因为 a[2] 加上 2 个 2 就是 a[6] 了。

母函数模板:

/**
 * @param {number} target
 * @param {array} arr
 * @return {number}
 */

// O(n^3)
function sum (target, arr) {
    // 如果要分解的数字小于等于 0,则方案数为 0
    if (target <= 0)
      return 0;

    // 如果第二个参数为空,则可以枚举的数为 1-target
    if (!arr) {
      arr = [];
      for (var i = 1; i <= target; i++)
        arr[i] = i;
    }

    var a = []
      , b = [];

    for (var i = 0; i <= target; i++)
      a[i] = b[i] = 0;

    // start
    a[0] = 1;

    // 枚举可以拼的数字
    for (var i = 0; i < arr.length; i++) {

      for (var j = 0; j <= target; j++)
        for (var k = 0; j + k <= target; k += arr[i])
          b[j + k] += a[j];

      for (var j = 0; j <= target; j++)
        a[j] = b[j], b[j] = 0;
    }

    return a[target];
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值