母函数

* 计算整数n的所有划分方法
* 通过母函数模板来计算整数划分,
* 多项式:(1+x+x^2+x^3+x^4+x^5+....)*(1+x^2+x^4+x^6+x^8+x^10+....)*(1+x^3+x^6+x^9+x^12....).....(#式)
* 本函数就是展开#式多项式,得到最后多项式的系数。
* c1、c2存储多项式的系数,比如多项式1+x+x^2+x^3+x^4+x^5+....,c1[0]=1,c1[1]=1,...,表示x的多少吃饭的系数为多少,如c2[3]=5,表示5x^3。
* c1保存最终的系数,c2保存当前相乘的2个多项式系数,如下:
* 第一个多项式(1+x+x^2+...)[i=1],我们直接保存在c1中,即c1[0...n]=1,
* 在上面保存的多项式(1+x+x^2+...)(1),与下一个括号(1+x^2+x^4+...)[i=2](2)相乘,模拟手工计算:
* 一、(1)中的1[j=0]和(2)中的每项[k=0...n]相乘,得到1+x^2+x^4+...,在把x^0(1)和(1+x+x^2+...)合并同类项c1[0],即幂数相同的系数相加,
* 如x^2和(1+x+x^2+...)中的x^2系数相加,而(1+x+x^2+...)所有系数保存在c2数组中, 所以和c1[2]的值相加,
* x^4在和(1+x+x^2+...)的c1[4]值相加,这样一直下去一直到整数n,因为整数拆分方案数就是最后x^n的系数。
* 二、(1)中的x[j=1]和(2)中的每项[k=0...n]相乘,得到x+x^3+x^5+...,在按照上面方法和c1合并相同幂的项,放到c2,比如x[j=1]和k[k=0]相乘,
* 即x^1 * x^0 , 得到的系数j+k,x^k[k=0]是(2)式得到的,系数为1,但x[j=1]的系数是c1[j],所以 x^(j+k)的系数是c2中原来的系数+c1[j]的值,因x^k系数为1,忽略。
* 三、这样循环下去,即可把(1+x+x^2+...)(1),(1+x^2+x^4+...)[i=2](2)展开,且各指数的系数放在c2中。在把c2中的系数放到c1中,计算与第三个式子展开(1+x^3+x^6+...)。
* 依次类推,一直到n

算法与代码

	/**
		 * 计算整数n的所有划分方法
		 * 通过母函数模板来计算整数划分,
		 * 多项式:(1+x+x^2+x^3+x^4+x^5+....)*(1+x^2+x^4+x^6+x^8+x^10+....)*(1+x^3+x^6+x^9+x^12....).....(#式)
		 * 本函数就是展开#式多项式,得到最后多项式的系数。
		 * c1、c2存储多项式的系数,比如多项式1+x+x^2+x^3+x^4+x^5+....,c1[0]=1,c1[1]=1,...,表示x的多少吃饭的系数为多少,如c2[3]=5,表示5x^3。
		 * c1保存最终的系数,c2保存当前相乘的2个多项式系数,如下:
		 * 第一个多项式(1+x+x^2+...)[i=1],我们直接保存在c1中,即c1[0...n]=1,
		 * 在上面保存的多项式(1+x+x^2+...)(1),与下一个括号(1+x^2+x^4+...)[i=2](2)相乘,模拟手工计算:
		 * 一、(1)中的1[j=0]和(2)中的每项[k=0...n]相乘,得到1+x^2+x^4+...,在把x^0(1)和(1+x+x^2+...)合并同类项c1[0],即幂数相同的系数相加,
		 * 如x^2和(1+x+x^2+...)中的x^2系数相加,而(1+x+x^2+...)所有系数保存在c2数组中, 所以和c1[2]的值相加,
		 * x^4在和(1+x+x^2+...)的c1[4]值相加,这样一直下去一直到整数n,因为整数拆分方案数就是最后x^n的系数。
		 * 二、(1)中的x[j=1]和(2)中的每项[k=0...n]相乘,得到x+x^3+x^5+...,在按照上面方法和c1合并相同幂的项,放到c2,比如x[j=1]和k[k=0]相乘,
		 * 即x^1 * x^0 , 得到的系数j+k,x^k[k=0]是(2)式得到的,系数为1,但x[j=1]的系数是c1[j],所以 x^(j+k)的系数是c2中原来的系数+c1[j]的值,因x^k系数为1,忽略。
		 * 三、这样循环下去,即可把(1+x+x^2+...)(1),(1+x^2+x^4+...)[i=2](2)展开,且各指数的系数放在c2中。在把c2中的系数放到c1中,计算与第三个式子展开(1+x^3+x^6+...),
		 * 依次类推,一直到n
		 * @param n 待划分的数
		 * @return 划分方案数
		 */
		public static int doWork(int n) {
				int[] c1 = new int[n+1];
				int[] c2 = new int[n+1];
				for(int i=0; i<=n; i+=1) {
						c1[i] = 1;
						c2[i] = 0;
				}
				for(int i=2; i<=n; i+=1) {
						for(int j=0; j<=n; j+=1) {
								for(int k=0; k+j<=n; k+=i) {
										c2[j+k] += c1[j];
								}
						}
						for(int j=0; j<=n; j+=1) {
								c1[j] = c2[j];
								c2[j] = 0;
						}
				}
				return c1[n];
		}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值