algorithm - 具有两个参数的递归函数的返回值

标签 algorithm recursion integer-partition

考虑以下整数分区代码:

int p (int n, int m)
{
    if (n == m)
        return 1 + p(n, m - 1);
    if (m == 0 || n < 0)
        return 0;
    if (n == 0 || m == 1)
        return 1;

    return p(n, m - 1) + p(n - m, m);

}

如果我以 p(7,3) 为例,函数变为 p(7,0) & p(4,3) 后会发生什么?

最佳答案

如果你有 Python,你可以玩这个:

def p(n,m):
    if n == m:
        return 1 + p(n,m-1)
    elif m == 0 or n < 0:
        return 0
    elif n == 0 or m == 1:
        return 1
    else:
        return p(n,m-1) + p(n-m,m)

def tupleFromString(s):
    #converts a string like `(3,7)` to the correspoding int tuple
    s = s.strip()
    arguments = s[1:len(s)-1].split(',')
    return tuple(int(i) for i in arguments)

def toString(t):
    #converts an int-tuple to a string, without the spaces
    return str(t).replace(' ','')

def expandOnce(s):
    s = s.strip()
    if s.startswith('p'):
        n,m = tupleFromString(s[1:])
        if n == m:
            return '1 + p' + toString((n,m-1))
        elif m == 0 or n < 0:
            return '0'
        elif n == 0 or m == 1:
            return '1'
        else:
            return 'p' + toString((n,m-1)) + ' + p' + toString((n-m,m))
    else:
        return s

def expandLine(line):
    return ' + '.join(expandOnce(term) for term in line.split('+'))

def expand(s):
    firstLine = True
    k = len(s)
    prefix = s + ' = '
    while 'p' in s:
        if firstLine:
            firstLine = False
        else:
            prefix = ' '*k + ' = '
        s = expandLine(s)
        print(prefix + s)
    print(prefix + str(sum(int(i) for i in s.split('+'))))

p(m,n)是函数的直接实现,expand将步骤显示为字符串:

>>> p(4,3)
4
>>> expand('p(4,3)')
p(4,3) = p(4,2) + p(1,3)
       = p(4,1) + p(2,2) + p(1,2) + p(-2,3)
       = 1 + 1 + p(2,1) + p(1,1) + p(-1,2) + 0
       = 1 + 1 + 1 + 1 + p(1,0) + 0 + 0
       = 1 + 1 + 1 + 1 + 0 + 0 + 0
       = 4

其逻辑如下。如果您想知道 p(4,3) 是什么,请查阅定义。 p(4,3)n = 4m = 3,因此您需要使用定义的最后一个子句。这告诉你

p(4,3) = p(4,3-1) + p(4-3,3)
       = p(4,2) + p(1,3)

除非您知道 p(4,2)p(1,3) 是什么,否则这无济于事,因此您回到定义并发现p(4,2) = p(4,1) + p(2,2)p(1,3) = p(1,2) + p(-1, 2)。结合以上内容,您现在知道

p(4,3) = p(4,3-1) + p(4-3,3)
       = p(4,2) + p(1,3)
       = p(4,1) + p(2,2) + p(1,3) + p(1,2)

在每个阶段,如果有一个看起来像 p(m,n) 的术语——您回到定义并查看它的含义。您最终会遇到 基本情况,例如 p(4,1) = 1。一旦所有的 p 都被评估——只需添加剩下的(只是一堆 1 和 0)。

同样,

p(7,3) = p(7,2) + p(4,3)
       = p(7,1) + p(5,2) + p(4,2) + p(1,3)
       = 1 + p(5,1) + p(3,2) + p(4,1) + p(2,2) + p(1,2) + p(-2,3)
       = 1 + 1 + p(3,1) + p(1,2) + 1 + 1 + p(2,1) + p(1,1) + p(-1,2) + 0
       = 1 + 1 + 1 + p(1,1) + p(-1,2) + 1 + 1 + 1 + 1 + p(1,0) + 0 + 0
       = 1 + 1 + 1 + 1 + p(1,0) + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0
       = 1 + 1 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0
       = 8

关于algorithm - 具有两个参数的递归函数的返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34838105/

相关文章:

java - 是否有一种有效的算法用于具有有限数量的部分的整数分区?

algorithm - 计算数字的不同方法

java - 覆盖更大线的最小线段数

查找可能的选择数量的算法

algorithm - 定义重叠元素或不包含在子集中的元素

c++ - 如何在深度优先搜索的递归实现中返回 bool 值?

linux命令行递归检查目录中至少有1个与目录同名的文件

algorithm - 起始位置和一组所需节点之间的最小生成树

java - 从矩阵的一点移动到零的位置

c++ - 就地共轭整数分区