- 描述
- 将正整数n表示成一系列正整数之和:n=n1+n2+…+nk,
其中n1≥n2≥…≥nk≥1,k≥1。
正整数n的这种表示称为正整数n的划分。求正整数n的不
同划分个数。
例如正整数6有如下11种不同的划分:
6;
5+1;
4+2,4+1+1;
3+3,3+2+1,3+1+1+1;
2+2+2,2+2+1+1,2+1+1+1+1;
1+1+1+1+1+1。
- 输入
- 第一行是测试数据的数目M(1<=M<=10)。以下每行均包含一个整数n(1<=n<=10)。
- 输出
- 输出每组测试数据有多少种分法。
- 样例输入
-
1 6
- 样例输出
-
11
先上代码:
#include<iostream> using namespace std; int q(int n,int m) //数字 n 进行划分,最大值为 m { if((n<1)||(m<1)) return 0; if((n == 1)||(m == 1)) return 1; if(n < m) return q(n,n); if(n == m) return q(n,m-1)+1; //不包含最大值 m + 只含最大值 m return q(n,m-1)+q(n-m,m); //不包含最大值 m + 只含最大值 m } int main() { int T,n; cin>>T; while(T--){ cin>>n; cout<<q(n,n)<<endl; } }
讨论五种情况:
①n=1:此时无论怎么划分,都只有一种情况。
②m=1:此时只有n个1这种划分情况。
③n<m:应该返回q(n,n),这很好理解,因为一个数不可能划分为比自己还大的数
④n=m:应该返回q(n,m-1)+1,看成 把n划分为【最大值为n-1的数】和【最大值只为n的数】。因为n=m,所以最大值为n的话,只有一种数,所以第二种情况为1
⑤n>m:应该返回q(n,m-1)+q(n-m,m)看成 把n划分为【最大值为m-1的数】和【最大值只为m的数】。看情况二,比如q(6,4),如果最大值只能为4的话,那么只有【4,2】和【4,1,1】两种情况。看红色部分,相当于把n减去m之后,最大值为m的划分,也就是q(n-m,m)
整数划分(二)
- 描述
-
把一个正整数m分成n个正整数的和,有多少种分法?
例:把5分成3个正正数的和,有两种分法:
1 1 3
1 2 2
- 输入
- 第一行是一个整数T表示共有T组测试数据(T<=50)
每组测试数据都是两个正整数m,n,其中(1<=n<=m<=100),分别表示要拆分的正数和拆分的正整数的个数。 - 输出
- 输出拆分的方法的数目。
- 样例输入
-
2 5 2 5 3
- 样例输出
-
2 2
代码:
#include<iostream> #include<cstdio> using namespace std; int q(int n,int m) //数字 n 划分为 m 个数字 { if(n<m) return 0; else if(n==m || m==1) return 1; else//一个数字能划分为 含有1的 和 不含有1的 return q(n-1,m-1)+q(n-m,m);//含有1的删掉一个1,n和m都减一。不含有1的所有数字都减一 } int main() { // freopen("2.txt","r",stdin); int T,n,m; scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); printf("%d ",q(n,m)); } }
递归,比如将7划分为3个正整数的和,肯定是1,1,5 1,2,4 ,1,3,3, 2,2,3;
这里分成两部分,一部分是包含1,即1,1,5, 1,2,4 1,3,3里面都有1,因此可以划分成1,5, 2,4 3,3(把1除掉) 另一
部分是不包含1,即2,2,3 ,可以将2,2,3分别减去1,即1,1,2,因此递归式就出来了,
q(7,3)=q(6,2)+q(4,3);
即q(m,n)=q(m-1,n-1)+q(m-n,n);
整数划分(三)
- 描述
-
整数划分是一个经典的问题。请写一个程序,完成以下要求。
- 输入
- 多组输入数据。
每组输入是两个整数n和k。(1 <= n <= 50, 1 <= k <= n) - 输出
- 对于输入的 n,k;
第一行: 将n划分成若干正整数之和的划分数。
第二行: 将n划分成k个正整数之和的划分数。
第三行: 将n划分成最大数不超过k的划分数。
第四行: 将n划分成若干个 奇正整数之和的划分数。
第五行: 将n划分成若干不同整数之和的划分数。
第六行: 打印一个空行 - 样例输入
-
5 2
- 样例输出
-
7 2 3 3 3