数的除法

Number of ways to divide a number

给定一个数字 N,打印它可以表示为

的多少种方式
N = a + b + c + d

1 <= a <= b <= c <= d; 1 <= N <= M

我的观察:

For N = 4: Only 1 way - 1 + 1 + 1 + 1

For N = 5: Only 1 way - 1 + 1 + 1 + 2

For N = 6: 2 ways     - 1 + 1 + 1 + 3
                        1 + 1 + 2 + 2

For N = 7: 3 ways     - 1 + 1 + 1 + 4
                        1 + 1 + 2 + 3
                        1 + 2 + 2 + 2

For N = 8: 5 ways     - 1 + 1 + 1 + 5
                        1 + 1 + 2 + 4
                        1 + 1 + 3 + 3
                        1 + 2 + 2 + 3
                        2 + 2 + 2 + 2

So I have reduced it to a DP solution as follows:
 DP[4] = 1, DP[5] = 1;

for(int i = 6; i <= M; i++)
   DP[i] = DP[i-1] + DP[i-2];

我的观察是正确的还是我遗漏了什么。我没有要 运行 的任何测试用例。所以请让我知道该方法是否正确。

我认为函数 f(N,m,n) 的定义,其中 N 是我们想要产生的总和,m 是总和中每一项的最大值,n 是其中的项数总和应该有效。

f(N,m,n) 定义为 n=1 如果 N > m 则为 0,否则为 N。

对于 n > 1,f(N,m,n) = 总和,对于 f(S-t, t, n-1) 从 1 到 N 的所有 t

这表示设置每一项,从右到左。

然后您可以使用此关系解决问题,可能使用记忆。

对于最大 n=4 和 N=5000,(并巧妙地实施以在存在 0 种可能性时快速计算),我认为这对于大多数目的来说可能足够快地计算出来。

不幸的是,你的递归是错误的,因为对于 n = 9,解是 6,而不是 8。

如果 p(n,k) 是将 n 分成 k 个非零整数部分的方法数,那么我们有

p(0,0) = 1
p(n,k) = 0 if k > n or (n > 0 and k = 0)
p(n,k) = p(n-k, k) + p(n-1, k-1) 

因为要么有一个值为 1 的分区(在这种情况下,将这部分去掉会产生一个 n-1 的分区为 k-1 个部分),要么你可以从每个分区中减去 1,得到一个 n - k.很容易证明这个过程是双射的,因此是递归的。

更新:

对于特定情况 k = 4,OEIS 告诉我们存在另一种仅依赖于 n 的线性递归:

a(n) = 1 + a(n-2) + a(n-3) + a(n-4) - a(n-5) - a(n-6) - a(n-7) + a(n-9)

这个递归可以通过标准方法求解得到一个明确的公式。我写了一个小SAGE script来解决它,得到了以下公式:

a(n) = 1/144*n^3 + 1/32*(-1)^n*n + 1/48*n^2 - 1/54*(1/2*I*sqrt(3) - 1/2)^n*(I*sqrt(3) + 3) - 1/54*(-1/2*I*sqrt(3) - 1/2)^n*(-I*sqrt(3) + 3) + 1/16*I^n + 1/16*(-I)^n + 1/32*(-1)^n - 1/32*n - 13/288

OEIS 也 gives the following simplification:

a(n) = round((n^3 + 3*n^2 -9*n*(n % 2))/144)

我还没有验证。

这是不正确的。这是正确的:

DP[n,k] 是将 n 表示为 k 个数之和的方法数。 那么你正在寻找DP[n,4]

DP[n,1] = 1
DP[n,2] = DP[n-2, 2] + DP[n-1,1] = n / 2
DP[n,3] = DP[n-3, 3] + DP[n-1,2]
DP[n,4] = DP[n-4, 4] + DP[n-1,3]

我只会解释最后一行,你马上就会明白,为什么其他人是对的。

让我们以 n=a+b+c+d.

为例

如果 a > 1,则 n-4 = (a-1)+(b-1)+(c-1)+(d-1)DP[n-4,4] 的有效总和。

如果 a = 1,则 n-1 = b+c+dDP[n-1,3] 的有效总和。

也反过来:

对于每个有效的 n-4 = x+y+z+t,我们有一个有效的 n=(x+1)+(y+1)+(z+1)+(t+1)

对于每个有效的 n-1 = x+y+z,我们有一个有效的 n=1+x+y+z

#include <iostream>

using namespace std;

int func_count( int n, int m )
{

     if(n==m)
        return 1;
     if(n<m)
        return 0;
     if ( m == 1 )
        return 1;
     if ( m==2 )
        return (func_count(n-2,2) + func_count(n - 1, 1));
     if ( m==3 )
        return (func_count(n-3,3) + func_count(n - 1, 2));

     return (func_count(n-1, 3) + func_count(n - 4, 4));
}

int main()
{

     int t;
     cin>>t;
     cout<<func_count(t,4);
     return 0;
}