题目90:整数划分
2017-11-28 23:38
381 查看
题目链接:
http://acm.nyist.net/JudgeOnline/problem.php?pid=90描述
将正整数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 |
算法思想:
生成函数解法(组合数学中应用的母函数)。先简单说明一下生成函数吧,下面是一个生成函数,
xk的系数ak代表了可获得数字k的组合数。
那么回到我们的问题中,我们怎么用生成函数去解决呢?
类似的,我们可以计算生成函数:
我们来做一个说明,第i个括号(1+xi+x2i+x3i · · ·)选择的元素代表了数字i在我们最终的划分中出现的次数,具体而言,如果我们在第i个括号中选择了元素 xc(i) * i 则表示数字 i 在我们最终的划分中出现了c(i)次。如果我们把最终从每个括号里面选择出来的元素相乘 x1 * c(1) · x2 * c(2) · x3 * c(3) · · · = x c(1) + 2 * c(2) + 3 * c(3)···.那么,xn的系数就是我们可以获得多少种不同的方式使得c(1) + 2 * c(2) + 3 * c(3)··· = n,也就是n的划分数(其中,c(i)代表了在一次划分中数字 i 的出现次数)。比如说25=6+4+4+3+2+2+2+1+1,用上式表示就是25=1(2)+2(3)+3(1)+4(2)+5(0)+6(1),也就是在划分中有两个1,三个2,一个3,两个4,0个5以及一个6。
假设x<1,那么我们可以将上面的生成函数表示为:
考虑到我们能选择的最大的数 i 是 m ,所以真正计算的时候我们需要对上面的生成函数式子做一下修改:
G(x) = (1+x+x^2+x^3+…+x^n) (1+x^2+x^4+…) (1+x^3+x^6+…) … (1+x^m)
= g(x,1) g(x,2) g(x,3) … g(x, n)
源代码
/* Author:杨林峰 Date:2017.11.28 NYOJ(90):整数划分 */ #include <iostream> #include <cstring> using namespace std; #define N 11 unsigned long a ;/*多项式a的系数数组*/ unsigned long b ;/*多项式b的系数数组*/ unsigned long c ;/*存储多项式a*b的结果*/ /*两个多项式进行乘法,系数分别在a和b中,结果保存到c ,项最大次数到N */ /*注意这里我们只需要计算到前N项就够了。*/ void Poly() { int i, j; memset(c, 0, sizeof(c)); for (i = 0; i<N; i++) for (j = 0; j<N - i; j++) /*y<N-i: 确保i+j不会越界*/ c[i + j] += a[i] * b[j]; } /*计算出前N项系数!即g(x,1) g(x,2)... g(x,n)的展开结果*/ void Init() { int i, k; memset(a, 0, sizeof(a)); memset(c, 0, sizeof(c)); for (i = 0; i<N; i++) a[i] = 1; /*第一个多项式:g(x, 1) = x^0 + x^1 + x^2 + x^3 + */ for (k = 2; k<N; k++) { memset(b, 0, sizeof(b)); for (i = 0; i<N; i += k) b[i] = 1;/*第k个多项式:g(x, k) = x^0 + x^(k) + x^(2k) + x^(3k) + */ Poly(); /* 多项式乘法:c= a*b */ memcpy(a, c, sizeof(c)); /*把相乘的结果从c复制到a中:c=a; */ } } int main() { int M, n; cin >> M; while (M--) { cin >> n; Init(); cout << c << endl; } return 0; }
相关文章推荐
- 南阳oj 题目 90 整数划分
- 搜索——Ny 90 整数划分
- nyoj 90 整数划分
- NYOJ 90 —— 求正整数n划分为若干个正整数的划分个数
- NYOJ 题目176整数划分(二)(递归)
- NYOJ-90整数划分
- nyoj 90 整数划分(一) (dp||递归)
- 【dp】NYOJ 90 整数划分
- 整数划分——真正的递归经典例题(NYOJ——90)
- NYOJ90 整数划分 【深搜】
- 51nod 1201:整数划分 超级好的DP题目
- nyoj-90-整数划分
- 测试数据整数搜索——Ny 90 整数划分
- nyoj 整数划分 90 (母函数)
- 南阳理工OJ_题目746 整数划分(四)
- nyoj 90 整数划分
- nyoj 90 整数划分 【深搜】
- 51nod 1201:整数划分 超级好的DP题目
- nyoj_90_整数划分_201403161553
- NYOJ 90 整数划分