整数拆分的可能数

题目:给定一个整数 \(n\) ,输出这个整数拆分的可能总数。

例如:\(n=6\) 时有

\( \begin{aligned} 6 &= 5+1 \\ &= 4+2=4+1+1 \\ &= 3+3=3+2+1 \\ &= 2+2+2=2+2+1+1=2+1+1+1 \\ &= 1+1+1+1+1+1 \\ \end{aligned} \)

\(11\) 种分解方法,所以输出应该为 11

使用母函数法:

整数分解用母函数可以这样理解,分别用任意个 \(1,2,3,4,\cdots,n\) 可以加起来可以表示成 \(n\) 的种数。又因为当使用整数 \(m\)\(n\) 进行分解时,所使用的次数不能多于 \(n/m\) 次,所以可以写下母函数如下:

\(\displaystyle G(x)=(1+x^1+x^2+\cdots+x^n)\times (1+x^2+x^4+\cdots+x^{\frac{n}{2} \cdot 2})\times \cdots\times (1+x^m+x^{2\cdot m}+x^{3\cdot m}+……+x^{\frac{n}{m}\cdot m})\times \cdots\times (1+x^n)\)

在程序中使用 \(s\) 数组表示每一轮乘法后得到系数,\(c\) 数组表示到现在为止乘法得到的系数总和。最后算出结果后 \(x^n\) 对应的系数则为可分解的可能数。

代码如下:

#include<cstdio>
const int num=405;
long long s[num];
long long c[num];

int main() {
	int n;
	while(scanf("%d",&n)!=EOF) {
		for(int i=0; i<num; i++) {
			c[i]=1;
			s[i]=0;
		}
		for(int i=2; i<=n; i++) {
			for(int j=0; j<=n; j+=i) {
				for(int k=0; j+k<=n; k++) {
					s[k+j]+=c[k];
				}
			}
			for(int x=0; x<=n; x++) {
				c[x]=s[x];
				s[x]=0;
			}
		}
		printf("%lld\n",c[n]);
	}
	return 0;
}

posted on 2024-03-30 22:17  White_Fang  阅读(62)  评论(0)    收藏  举报

导航