分拆数 【生成函数】

orzzzzzzzzzzzzzzzzzzz

求整数n的不同拆分方案数

多项式可以做到O(nlogn)

窝们先可以得到它的生成函数

f(x)=1ni=1(1xi)

对两边同时取对
lnf(x)=i=1nln(1xi)

右边泰勒展开得到多项式
A(x)=i=1nj>=1xijj=j>=11ji=1nxij

虽然是指数也是可以模掉xn的,所以ij<=n,复杂度就是O(nlogn)
现在就只需要求
f(x)=eA(x)

滋磁!

f(x)=lnA(x) :

B(A(x))=ln(A(x))

则有
B(A(x))=A(x)A(x)

f(x)=eA(x)

设已经求出了f(x)的前n项f0(x)

f(x)f0(x)(mod xn)

g(f(x))=lnf(x)A(x)=0

泰勒展开得
0g(f0(x))+g(f0(x))(f(x)f0(x)) (mod x2n)

所以有
f(x)f0(x)g(f0(x))g(f0(x)) (mod x2n)

f(x)=f0(x)lnf0(x)A(x)1f0(x)=f0(x)(1lnf0(x)+A(x))

分拆是指将一个正整 $n$ 表示成若干个正整之和的不同方式的目。以下是几种生成分拆的方法: ### 递归方法 递归的基本思想是利用分拆的递推关系。设 $p(n, k)$ 表示将 $n$ 分拆成不大于 $k$ 的正整之和的分拆。则有递推公式: - 当 $n = 0$ 时,$p(n, k) = 1$,表示有一种分拆方式(即不选任何)。 - 当 $n < 0$ 或 $k = 0$ 时,$p(n, k) = 0$,表示没有分拆方式。 - 当 $n \geq k$ 时,$p(n, k) = p(n, k - 1) + p(n - k, k)$,其中 $p(n, k - 1)$ 表示分拆中不包含 $k$ 的分拆,$p(n - k, k)$ 表示分拆中至少包含一个 $k$ 的分拆。 以下是使用 Python 实现的递归代码: ```python def partition_recursive(n, k): if n == 0: return 1 if n < 0 or k == 0: return 0 return partition_recursive(n, k - 1) + partition_recursive(n - k, k) def partition(n): return partition_recursive(n, n) # 示例:计算 5 的分拆 print(partition(5)) ``` ### 动态规划方法 动态规划是通过填充一个二维组来避免递归中的重复计算。以下是使用 Python 实现的动态规划代码: ```python def partition_dp(n): dp = [[0] * (n + 1) for _ in range(n + 1)] for k in range(1, n + 1): dp[0][k] = 1 for i in range(1, n + 1): for j in range(1, n + 1): if i < j: dp[i][j] = dp[i][i] elif i == j: dp[i][j] = dp[i][j - 1] + 1 else: dp[i][j] = dp[i][j - 1] + dp[i - j][j] return dp[n][n] # 示例:计算 5 的分拆 print(partition_dp(5)) ``` ### 欧拉生成函数方法 分拆生成函数为: $$P(x)=\prod_{k = 1}^{\infty}\frac{1}{1 - x^k}=1 + x + 2x^2 + 3x^3 + 5x^4 + 7x^5+\cdots$$ 可以通过多项式乘法来计算分拆。不过这种方法在实现上相对复杂,通常在计算机中使用前面两种方法更为常见。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值