数的划分(递归)

整数划分是另外的问题:

题目描述 Description

将整数n分成k份,且每份不能为空,任意两种划分方案不能相同(不考虑顺序)。
例如:n=7,k=3,下面三种划分方案被认为是相同的。
7=1+1+5
7=1+5+1
7=5+1+1
问有多少种不同的分法。

输入描述 Input Description

输入:n,k
(1< =n <= 200,1<= k <= 6)

输出描述 Output Description

输出:一个整数,即不同的分法

样例输入 Sample Input

7 3

样例输出 Sample Output

4

数据范围及提示 Data Size & Hint

四种分法为:
1+1+5;
1+2+4;
1+3+3;
2+2+3;

解决思路:

设 f(n,m) 为整数 n 拆分成 m 个数字的方案数.
那么对于每一个情况一定可以分为以下两种情况,且不重不漏。
1.不选 1 的情况
如果不选择 1,我们把 n 拆分成 m 块的情况,可以等价于将每一块都减去1,然后分为m块,即 f(n-m,m)
2.选 1 的情况
那么就是其中一块肯定有一个 1,然后对n-1分成m-1块,即 f(n-1,m-1)。

所以总递推式为 f(n,m)=f(n-m,m)+f(n-1,m-1)

递归结束的条件是
1.n=0 或 n

代码:

#include<iostream>  
using namespace std;  
int dfs(int n,int k)  //把n整数划分成k份  
{  
    if(n==0||n<k||k==0)return 0;  //无法继续划分  
    if(k==1||n==k)return 1;       //只能划分成一项  
    return dfs(n-1,k-1)+dfs(n-k,k);  
}  
int main()  
{  
    int n,k;  //把n整数划分成k份  
    cin>>n>>k;  
    int x=dfs(n,k);  
    cout<<x<<endl;  
    return 0;  
}  

把所有情况输出:

代码:

#include <iostream>
#include <stdio.h>
using namespace std;
#define Max 100
int parts;
//整数n分成k份,不考虑顺序,譬如把3分成2份,1 2 和 2 1 是同一种情况。 统计所有情况
int divideNtoKpart(int n,int k,int start)//n:整数,k:分成k份 start:从start开始分类
{
    if (k==1) {
        return 1;
    }
    int sum=0;
    for (int i=start; i<=n/k; i++) {
        sum = sum + divideNtoKpart(n-i, k-1, i);
    }
    return sum;
}
//统计情况并输出所有情况
int divideNtoKpartAndPrintAllConditions(int n,int k,int start,int condition[Max],int index)
{       //n:整数,k:分成k份 start:从start开始分类 数组condition[Max]:存储分类的情况  index:数组下标,从0开始
    if (k==1) {
        condition[index]=n;
        for (int m=0; m<parts; m++) {
            cout<<condition[m]<<" ";
        }
        cout<<endl;
        return 1;
    }
    int sum=0;

    for (int i = start; i<=n/k; i++) {
        condition[index]=i;
        sum = sum + divideNtoKpartAndPrintAllConditions(n-i, k-1, i, condition, index+1);
    }
    return sum;
}
int main(int argc, const char * argv[]) {
    // insert code here...

    int n=0,k=0;
    int conditions[Max];
    cout<<"输入整数n"<<endl;
    cin>>n;
    cout<<"输入份数k"<<endl;
    cin>>k;
    parts=k;
    cout<<divideNtoKpartAndPrintAllConditions(n, k, 1, conditions, 0)<<"种"<<endl;
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章