Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 整数划分(算法和递归)_Algorithm_Recursion_Integer Partition - Fatal编程技术网

Algorithm 整数划分(算法和递归)

Algorithm 整数划分(算法和递归),algorithm,recursion,integer-partition,Algorithm,Recursion,Integer Partition,查找一个和数的多少个组合(代码中的变量n)。例如: 3=1+1+1=2+1=3=>ANS是3 5=5=4+1=3+2=3+1+1=2+2+1=2+1+1=1+1+1+1=>ANS为7 在下面的示例中,m是最大数,n是总和, 目的是找出它有多少个(和)组合 我只是想知道为什么p(n,m)=p(n,m-1)+p(n-m,m) 代码如下: int p (int n, int m) { if (n == m) return 1 + p(n, m - 1); if (m =

查找一个和数的多少个组合(代码中的变量n)。例如:

3=1+1+1=2+1=3=>ANS是3

5=5=4+1=3+2=3+1+1=2+2+1=2+1+1=1+1+1+1=>ANS为7

在下面的示例中,m是最大数,
n
是总和, 目的是找出它有多少个(和)组合

我只是想知道为什么p(n,m)=p(n,m-1)+p(n-m,m)

代码如下:

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);

}
intp(intn,intm)
{
如果(n==m)
返回1+p(n,m-1);
如果(m==0 | | n<0)
返回0;
如果(n==0 | | m==1)
返回1;
返回p(n,m-1)+p(n-m,m);
}
谢谢

表示
p(n,m)
为其和为
n
且每个加数小于或等于
m
的所有组合的数量。这里的关键是要证明以下递推方程:

p(n, m) - p(n, m - 1) = p(n-m, m)          (1)
(1)的左边是p(n,m)和p(n,m-1)的差,p(n,m-1)是至少包含一个
m
作为加数的所有组合的数量,剩余的和是
n-m
(这样总的是
n
),而且每个加数都小于或等于
m
。但这恰恰意味着p(n-m,m),它是(1)的右边


显然,问题的答案应该是p(n,n)。

首先,有关此函数的更多信息,请参阅

对于这个公式,请记住
p(n,m)
被定义为
n
的分区数,其最大成员最多为
m

因此
p(n,m)
m
的分区数,其最大成员最多为
m
。让我们根据最大的成员是否实际是
m
来划分它们

最大成员为
m
的分区数是填写
n=m+…
的方式数,这是
n-m
的分区数,其最大成员最多为
m
,根据定义为
p(n-m,m)

根据定义,
n
的最大成员最多为
m-1
的分区数是
p(n,m-1)


因此
p(n,m)=p(n-m,m)+p(n,m-1)

考虑通过添加一些小于或等于
m
的数字来产生
n
的所有方法。正如你所说,我们称之为
p(n,m)
。例如,p(7,3)=8,因为有8种方法可以将小于3的数字变成7,如下所示:(为了简单起见,我们可以假设我们总是按照从最大到最小的顺序添加数字)

  • 3+3+1
  • 3+2+2
  • 3+2+1+1
  • 3+1+1+1+1+1
  • 2+2+2+1
  • 2+2+1+1+1+1
  • 2+1+1+1+1+1+1
  • 1+1+1+1+1+1+1+1+1
现在我们可以将这些组合分为两组:

  • 第一个元素等于
    m
    (=3)的组合:

    • 3+3+1
    • 3+2+2
    • 3+2+1+1
    • 3+1+1+1+1+1
  • 第一个元素小于
    m
    的组合:

    • 2+2+2+1
    • 2+2+1+1+1+1
    • 2+1+1+1+1+1+1
    • 1+1+1+1+1+1+1+1+1
  • 因为
    p(n,m)
    组合的每个成员将在组1或组2中,我们可以说
    p(n,m)=大小(组1)+大小(组2)
    。现在如果我们通过替换证明
    size(Group1)=p(n-m,m)
    size(Group2)=p(n,m-1)
    ,我们得到
    p(n,m)=p(n-m,m)+p(n,m-1)

    验证
    大小(组1)=p(n-m,m)
    : 根据上述定义,
    p(n-m,m)
    是通过添加一些小于或等于
    m
    的数字来产生
    n-m
    的方法的数量


    • 如果将
      m
      附加到
      p(n-m,m)
      的每个组合中,它将成为组1的成员。所以
      p(n-m,m)size(Group2)=p(n,m-1)

      你想一个接一个地计算每个排列吗?我认为它是组合,在这种情况下3+2和2+3没有区别。我猜它来自这里:它不一样,这里的函数使用的数字不大于m(小于或等于),但是wiki中的情况是使用大于或等于k的数字。我想您希望我们通过组合参数来证明
      p(n,m)
      的递归关系,但是您忘了给出该函数的组合定义!这不是一个公平的问题。我只是不明白为什么剩下的是p(n-m,m),可以用其他方式解释吗?如果你能用中文解释得更详细些就更好了@我不确定用中文回答是否好。让我们这样想:所有在P(n,m)中但不在P(n,m-1)中的组合的特征是什么?首先,这些组合必须有一个固定的成员,即,
      m
      (否则它也将属于p(n,m-1))。其次,其余成员的总和必须是
      n-m
      (s.t.总总和是
      n
      )。此外,其余成员最多可以是
      m
      。因此,这些组合的数量应为
      p(n-m,m)
      。明白了吗?有谁能告诉我,在考虑返回值0和1的情况下,在p(4,3)之后,3+3+13+2+2+1+13+1+1+1的值是如何生成的。
              / 0 (k>n)
      p(k,n)={  1 (k=n)
              \ p(k+1,n)+p(k,n-k) (k<n)