使用递归计算(n + r)!/(n!* r!)

时间:2020-05-05 20:15:44

标签: c

#include<stdio.h>
int func(int n, int r);
int main(){
    int n,r;
    int result=0;
    printf("Enter the number:\n");
    scanf("%d",&n);
    printf("Enter the 2.number:\n");
    scanf("%d",&r);

   result=func(n,r);
   printf("%d",result);

    return(0);
}
int func(int n, int r){
    if(r==1){
        return(n);
    }
   if(n>0 && r>0){
       return ((n+r) / (n*r))* func(n-1,r-1);
   }
}

我写了代码,但是没有用。我输入n = 5且r = 2,结果为0。我想递归地计算它。我想计算(n + r)!/(n!* r!)

3 个答案:

答案 0 :(得分:3)

组合公式(n + r)! /(n!* r!)可以写为

( 1 * 2 * 3 ... * n+r ) / (( 1 * 2 * 3 ... * n ) * ( 1 * 2 * 3 ... * r ))

排除常见术语是:

( n+1 * n+2 ... * n+r ) / ( 1 * 2 * 3 ... * r)

这表明从1到r的简单循环。在每个步骤中,较高的乘积将被下一个较低的项整除,例如,任何两个连续的数字均可以被2除,任意的三个被3除以此类推。

示例n = 100,r = 5

1 * 101 / 1
101 * 102 / 2
5151 * 103 / 3
176851 * 104 / 4
4598126 * 105 / 5
= 96560646

答案 1 :(得分:1)

这是因为您使用的是int

改为尝试double


详细说明:

对于n = 5和r = 2,这部分:(n+r) / (n*r)将为7/10。

结果将放入int中,但是int不允许小数,并且将是floored,因此将是0


如果您的要求是使用递归和int,则需要重写算法。虽然,我不知道将小数表示为int会有意义。

您可以为(n + r)拆分计算!和(n!* r!),它们将通过您的算法轻松处理(小心,可能会迅速导致溢出),并在以后划分。


无论如何,通过做一些数学运算,它将变得更容易,也许有一种方法可以简化问题。

答案 2 :(得分:1)

如果要使用int和递归,则需要设计一个更好的算法。
首先请注意,A=(n+r)!/n!等于(n+r)(n+r-1)...(n+1)
然后,也有可能证明$ A / r!$是某个整数。

所以一个想法是,首先使用递归来计算A,然后使用递归来计算B=r!

代码看起来像这样:(假设n是全局的)

long long computeA(int currentn){
    if (currentn==n+1){
        return n+1;
    }
    return currentn*computeA(currentn-1);
}

long long computeB(int currentr){
    if (currentr==1){
        return 1;
    }
    return currentr*computeB(currentr-1);
}

int main(){
    /* whatever */
    long long A;
    A=computeA(n+r);
    long long B;
    B=computeB(r);
    printf("%lld",A/B);
    /* whatever */
}

请注意,a!会变得非常大,大约a>20。小心点。