【递归分治】整数划分的GO语言实现

 

  • 个人主页:我的主页
  • 座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物.

目录

前言

问题描述

问题分析

代码

结尾


前言

本文是学习算法分析中的递归分治思想,并解对于整数划分问题的实战运用。文末对经过分析后的递归策略,用GO语言进行了编码验证。


问题描述

一个正整数可以写成一些正整数的和,也就是指把一个正整数n如下如下形式:

n = n1 + n2 + ... + nk (其中 n1 >= n2 ... >= nk > 0, k >= 1),

最常见的问题就是给定正整数n,求不同数组(n1,n2,…, nk)的数目 p(n)。

问题分析

先来举个例子,以6来举例,有如下划分11种不同的划分,所以p(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;

正整数n的所有不同划分中,将最大加数n1 不大于 m 的情况记为q(n,m),这个称作n的m划分。

我们可以建立如下递归关系。

  1. (1)q(n, 1) = 1, n>=1 ;

当最大加数n1为1时,也就是1+…+1 = n这一种形式

  1. (2)q(n, m) = q(n , n), m >= n;

最大加数 n1当然不能大于 n, 所以划分数m >= n时, 也就相当于 n 的 n划分;其中特殊的有 q(1, m) = 1;

  1. (3) q(n, n) = 1 + q(n, n - 1);

正整数n 的划分 可以分解为 最大加数为 n1 = n的划分和 n1 <= n - 1的划分;此时 n1 = n时,只有一种划分,也就是p(6)中的第一个划分,所以就是这里的加1 。

  1. (4) q(n, m) = q(n, m - 1) + q(n - m, m), 当 n > m > 1时;

这里是最难理解的。当 n > m > 1时,我们最大加数n1=m和n1 <m分解为两个子问题:

  • 一是 最大加数 n1 = m 时,剩下的数就为  n - m,也就是n - m 的 m划分。这里已经假定 n1 = m的情况,即q(n - m, m);
  • 二是 最大加数 n1 <= m - 1时,也就是 n 的 m - 1划分,q(n , m - 1);

代码

上面按照递归分治的思想将问题分解成子问题,可以递归解决了,现在用代码实现如下:

package main

import (
        "fmt"
)

func q(n int, m int)(res int) {
        if((n < 1) || (m < 1)) {
                return 0
        }

        if((n == 1) || (m == 1)) {
                return 1
        }

        if(n < m)  {
                return q(n, n)
        }

        if(n == m) {
                return 1 + q(n, m - 1)
        }

        return q(n - m, m) + q(n, m - 1)
}

func main() {
        for i:=1; i<30; i++ {
                for j:=1; j<i+1; j++ {
                        fmt.Println("q(",i,",",j ,")=",q(i,j))
                }
        }
}


结尾

作者邮箱:[email protected]
如有错误或者疏漏欢迎指出,互相学习。

注:未经同意,不得转载!

猜你喜欢

转载自blog.csdn.net/senllang/article/details/129652394