整数划分

BG


没啥好说的,现在才搞的确有点晚了。。

问题


又叫做拆分数
给定正整数n,求将n拆分成若干正整数的和的方案数,其中又分为可相同和不可相同两个问题

整数划分1


考虑每个数字不能相等要怎么做
一个经典的dp是设f[i,j]表示拆分成i个数字,它们的和为j的方案数。
我们钦定所有数字降序排列,那么每次可以新增一个数字,或者全部加一,因此 f [ i , j ] = f [ i − 1 , j − i ] + f [ i , j − i ] f[i,j]=f[i-1,j-i]+f[i,j-i] f[i,j]=f[i1,ji]+f[i,ji]

可以发现i是 n \sqrt n n 级别的,这样做就是 O ( n n ) O(n\sqrt n) O(nn )的,并且多组询问直接 O ( n ) O(n) O(n)求和就没了

整数划分2


同样考虑dp,这个问题可以看成有n个体积为1~n的物品装满容量为n的完全背包的方案数
不妨设 m = n m=\sqrt n m=n ,对于体积 ≤ m \le m m的物品只有n种,因此做完全背包是 O ( n n ) O(n\sqrt n) O(nn )
对于体积 ≥ m \ge m m的物品总共只会选 n \sqrt n n 个,设f[i,j]表示i个数字和为j的方案数,转移 f [ i , j ] = f [ i − 1 , j − m ] + f [ i − 1 , j − i ] f[i,j]=f[i-1,j-m]+f[i-1,j-i] f[i,j]=f[i1,jm]+f[i1,ji]

当然最后还要合并两个背包,这样做总的复杂度是 O ( n n ) O(n\sqrt n) O(nn )的,并且不支持多组询问。。
在这里插入图片描述
考虑这样一个函数 P ( x ) = ∏ i ≥ 0 ( 1 1 − x i ) P(x)=\prod\limits_{i\ge0}\left(\dfrac{1}{1-x^i}\right) P(x)=i0(1xi1)
和这样一个函数 Q ( x ) = ∏ i ≥ 0 ( 1 − x i ) Q(x)=\prod\limits_{i\ge0}\left(1-x^i\right) Q(x)=i0(1xi)
显然 P ( x ) Q ( x ) = 1 P(x)Q(x)=1 P(x)Q(x)=1,并且 P ( x ) P(x) P(x)是整数拆分的生成函数

五边形数定理:
Q ( n ) = ∑ i = − ∞ ∞ ( − 1 ) i x i ( 3 i − 1 ) 2 = 1 + ∑ i = 1 ∞ ( − 1 ) i x i ( 3 i ± 1 ) 2 Q(n)=\sum_{i=-\infty}^{\infty}(-1)^ix^{\frac{i(3i-1)}{2}}=1+\sum_{i=1}^{\infty}(-1)^ix^{\frac{i(3i\pm1)}{2}} Q(n)=i=(1)ix2i(3i1)=1+i=1(1)ix2i(3i±1)
具体的证明可以看这里

由于五边形数是n2级别的,因此递推这个东西是 O ( n n ) O(n\sqrt n) O(nn )的,并且资瓷多组询问

在这里插入图片描述
考虑在模意义下做这个问题,我们可以用多项式ln+多项式exp做到 O ( n l o g n ) O(nlogn) O(nlogn)
具体看这里

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值