整数划分问题是算法中的一个经典命题之一,有关这个问题的讲述在讲解到递归时基本都将涉及。所谓整数划分,是指把一个正整数n写成如下形式:
n=m1+m2+...+mi; (其中mi为正整数,并且1 <= mi <= n),则{m1,m2,...,mi}为n的一个划分。
递归法:
递推表达式如下:
f(n, m)= 1; (n=1 or m=1) //1划分为m份,或n划分为1份
f(n, n); (n<m)
1+ f(n, m-1); (n=m) //分成的份数中没有为0的(即全为1相加),有0的则为f(n,m-1)划分
f(n-m,m)+f(n,m-1); (n>m)
实例应用:7个苹果放入三个盘子(无重复).
第一类: n个苹果放入m个盘子中,三个盘子都不为空,每个盘子先放一个,问题等同于n-m个苹果放入m个盘子中,即为d(n-m,m);
第二类: n个苹果放入m个盘子中,三个盘子有一个盘子为空,则等同于n个苹果再放入m-1个盘子,即d(n,m-1);
#include<stdio.h>
#include<string>
int partitionHelp(int n,int m)
{
if(n<1 ||m<1)
{
return 0;
}
else if(n==1 ||m==1)
{
return 1;
}
else if(n<m)
{
return partitionHelp(n,n);
}
else if(n==m)
{
return 1+partitionHelp(n,n-1);
}
else
{
return partitionHelp(n,m-1)+partitionHelp(n-m,m);
}
}
void main()
{
int number = 0;
number = partitionHelp(7,3);
printf("%d\n",number);
}
下面的另一解法从网上寻得:
#include <iostream>
using namespace std;
int a[10]={0};
int len = 0;
int count = 0;
void fun(int n,int m){
if(n==0){ //所求数已被全部分划
count++;
cout<<a[0];
for(int i=1;i<m;++i)
cout<<"+"<<a[i];
if(m > len){
cout<<endl; //到每行最后一列长度m都为len+1,此时应换行
++len;
}
else
cout<<",";
return;
}
for(int i=n;i>=1;--i){ //按从大到小的顺序划分整数
if(m==0||i<=a[m-1]) { //右边的数不能大于左边的数
a[m]=i;
fun(n-i,m+1);
}
}
}
int main() {
int n,m=0;
cin>>n; //输入一个1-10的整数
fun(n,m); //递归的方法打印所有的整数分划
cout << endl << "总数目: " << count << endl;
return 0;
}
本文详细介绍了整数划分问题的概念及解决方法,包括递归法的递推表达式及其应用场景。并通过实例演示了如何将一个正整数划分成若干个正整数之和的过程。
673

被折叠的 条评论
为什么被折叠?



