整數划分問題之遞歸法


整數划分問題是算法中的一個經典命題之一,有關這個問題的講述在講解到遞歸時基本都將涉及。所謂整數划分,是指把一個正整數n寫成如下形式:

    n=m1+m2+...+mi; (其中mi為正整數,並且1 <= mi <= n),則{m1,m2,...,mi}為n的一個划分。

如果{m1,m2,...,mi}中的最大值不超過m,即max(m1,m2,...,mi)<=m,則稱它屬於n的一個m划分。這里我們記n的m划分的個數為f(n,m);

例如但n=4時,他有5個划分,{4},{3,1},{2,2},{2,1,1},{1,1,1,1};

注意4=1+3 和 4=3+1被認為是同一個划分。

該問題是求出n的所有划分個數,即f(n, n)。下面我們考慮求f(n,m)的方法;

分析:

我們可以分為四種:

1. m=1 or n=1

只有一種划分情況,就是n個1相加, 所以f(n,m)=1;

2. m=n>1

f(n,m)=f(n,n-1)+1  加上的1代表n+0=n這個划分方案

3.n<m

f(n,m)=f(n,n) 邏輯上不存在m>n這種情況

4.n>m

f(n,m)=f(n,m-1)+f(n-m,m)

f(n,m-1)表示划分方案中沒有m的情況

f(n-m,m)表示划分方案中有m的情況

下面我們來看一個例子,可以更好的理解哦

整數4 最大加數 3
1+3=4
1+1+2=4
2+2=4
1+1+1+1=4
一共4種划分方案

分析:

沒有m的情況:

1+1+2=4
2+2=4
1+1+1+1=4

符合f(n,m-1)

有m的情況:

1+3=4

符合f(n-m,m)

代碼如下:

/*
整數划分問題
:將一個整數划分為若干個數相加
例子:
整數4 最大加數 4
4=4
1+3=4
1+1+2=4
2+2=4
1+1+1+1=4
一共五種划分方案
注意:1+3=4,3+1=4被認為是同一種划分方案
*/

#include<stdio.h>
int q(int n,int m)//n表示需要划分的數字,m表示最大的家數不超過m
{
    if(m==1||n==1)//只要存在一個為1,那么划分的方法數肯定只有一種,那就是n個1相加
    {
        return 1;
    }else if(n==m&&n>1)//二者相等且大於1的時候,問題等價於:q(n,n-1)+1;意味着將最大加數減一之后n的划分數,然后加一,最后面那個一代表的是:0+n,這個划分的方案
    {
        return q(n,n-1)+1;
    }else if(n<m)//如果m>n,那么令m=n就ok,因為最大加數在邏輯上不可能超過n
    {
        return q(n,n);
    }else if(n>m)
    {
        return q(n,m-1)+q(n-m,m);//分為兩種:划分方案沒有m的情況+划分方案有m的情況
    }
    return 0;
}
int main()
{
    printf("請輸入需要划分的數字和最大家數:\n");
    int n,m;
    scanf("%d %d",&n,&m);
    int r=q(n,m);
    printf("%d\n",r);
    return 0;
}

技術在於分享

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM