之前在长沙写的,发现自己又忘了,于是拿出来。。
感觉dp还比较有用,五边形数什么的也就是bike这种毒瘤出题人会考吧。。。
把整数n拆成若干整数的和,问方案数。
1.完全背包:O(n^2)
2. f ( i , j ) f(i,j) f(i,j)表示j拆成i个数的方案数,有
f ( i , j ) = f ( i , j − i ) + f ( i − 1 , j − 1 ) f(i,j)=f(i,j-i)+f(i-1,j-1) f(i,j)=f(i,j−i)+f(i−1,j−1) (放入一个1或所有数大小+1)
时间复杂度O(n^2)
拓展:
1)拆成两两不同的整数时,不能连续放入两个1而不进行所有数+1操作,即放入1前一次操作只能是+1,
f ( i , j ) = f ( i , j − i ) + f ( i − 1 , j − 1 − ( i − 1 ) ) = f ( i , j − i ) + f ( i − 1 , j − i ) f(i,j)=f(i,j-i)+f(i-1,j-1-(i-1))=f(i,j-i)+f(i-1,j-i) f(i,j)=f(i,j−i)+f(i−1,j−1−(i−1))=f(i,j−i)+f(i−1,j−i)
因为数两两不同,最多只有 n \sqrt n n个数( ( 1 + n ) ∗ n > n (1+\sqrt n)*\sqrt n>n (1+n)∗n>n),复杂度为O(n*sqrt(n))。
再拓展:如果只能用 ≤ x \leq x ≤x的数怎么做?每次 f ( i , v ) − = f ( i − 1 , v − ( x + 1 ) ) f(i,v)-=f(i-1,v-(x+1)) f(i,v)−=f(i−1,v−(x+1))即可
2)拆成全部为奇数的数的方案等于拆成两两不同数的方案,
3)拆成若干小于等于k的数等价于拆成小于等于k个任意大小的数(转置)。
3.对于2中的dp,将小于 n \sqrt n n的部分做背包,大于 n \sqrt n n的部分做dp,可以做到 n ∗ n n*\sqrt n n∗n的复杂度,但是只能回答一组询问,因为合并两部分是 n ∗ n n*\sqrt n n∗n的复杂度。(51nod 1597 有限背包计数问题)
4.如何解决多组询问?引入五边形数定理。
显然, f n = f n − 1 + 3 ∗ n − 2 = 1 + 3 ∗ ( 2 + n ) ∗ ( n − 1 ) 2 − 2 ∗ ( n − 1 ) = n ∗ ( 3 ∗ n − 1 ) 2 f_n=f_{n-1}+3*n-2=1+3*\frac{(2+n)*(n-1)}{2}-2*(n-1)=\frac{n*(3*n-1)}{2} fn=fn−1+3∗n−2=1+3∗2(2+n)∗(n−1)−2∗(n−1)=2n∗(3∗n−1)
前几个五边形数:1,5,12,22,35,51,70,92,117,145,176,210,247,287……
n取0,1,-1,2,-2,3,-3,……,值取绝对值
前几个广义五边形数:0,1,2,5,7,12,15,22,26,35,40,51,57,70,77,92,100,117,126……
ϕ ( x ) = ∏ i = 1 + ∞ ( 1 − x i ) \phi(x)=\prod_{i=1}^{+\infty}(1-x^i) ϕ(x)=i=1∏+∞(1−xi)
ϕ ( x ) = 1 − x − x 2 + x 5 + x 7 − x 12 − x 15 + x 22 + x 26 … … = 1 + ∑ i = 1 + ∞ ( − 1 ) i ( x i ∗ ( 3 ∗ i − 1 ) 2 + x ( − i ) ∗ ( 3 ∗ ( − i ) − 1 ) 2 ) \phi(x)=1-x-x^2+x^5+x^7-x^{12}-x^{15}+x^{22}+x^{26}……=1+\sum_{i=1}^{+\infty}(-1)^i(x^{\frac{i*(3*i-1)}{2}}+x^{\frac{(-i)*(3*(-i)-1)}{2}}) ϕ(x)=1−x−x2+x5+x7−x12−x15+x22+x26……=1+i=1∑+∞(−1)i(x2i∗(3∗i−1)+x2(−i)∗(3∗(−i)−1))
写出整数划分的生成函数:
G ( x ) = ∏ i = 1 + ∞ ( 1 + x i + x 2 ∗ i + x 3 ∗ i … … ) = ∏ i = 1 + ∞ 1 1 − x i G(x)=\prod_{i=1}^{+\infty} (1+x^i+x^{2*i}+x^{3*i}……)=\prod_{i=1}^{+\infty} \frac{1}{1-x^i} G(x)=i=1∏+∞(1+xi+x2∗i+x3∗i……)=i=1∏+∞1−xi1
发现 G ∗ ϕ = 1 G*\phi=1 G∗ϕ=1
于是有 G ( 1 ) = 1 , G ( n ) ∗ ϕ ( 0 ) + G ( n − 1 ) ∗ ϕ ( 1 ) + G ( n − 2 ) ∗ ϕ ( 2 ) + G ( n − 5 ) ∗ ϕ ( 5 ) … … = 0 G(1)=1,G(n)*\phi(0)+G(n-1)*\phi(1)+G(n-2)*\phi(2)+G(n-5)*\phi(5)……=0 G(1)=1,G(n)∗ϕ(0)+G(n−1)∗ϕ(1)+G(n−2)∗ϕ(2)+G(n−5)∗ϕ(5)……=0
G ( n ) = G ( n − 1 ) + G ( n − 2 ) − G ( n − 5 ) + … … G(n)=G(n-1)+G(n-2)-G(n-5)+…… G(n)=G(n−1)+G(n−2)−G(n−5)+……
因为五边形数是n^2级别的,所以递推求G(n)的复杂度为n*sqrt(n)。
拓展:求每个整数出现次数小于k的划分数
G ′ ( x ) = ∏ i = 1 + ∞ 1 − x i ∗ k 1 − x i G'(x)=\prod_{i=1}^{+\infty}\frac{1-x^{i*k}}{1-x^i} G′(x)=i=1∏+∞1−xi1−xi∗k
G ′ ( x ) = G ( x ) ∗ ϕ ( x k ) = G ( x ) ∗ ( 1 − x k − x 2 ∗ k + x 5 ∗ k + x 7 ∗ k − x 12 ∗ k − x 15 ∗ k + x 22 ∗ k … … ) G'(x)=G(x)*\phi(x^k)=G(x)*(1-x^k-x^{2*k}+x^{5*k}+x^{7*k}-x^{12*k}-x^{15*k}+x^{22*k}……) G′(x)=G(x)∗ϕ(xk)=G(x)∗(1−xk−x2∗k+x5∗k+x7∗k−x12∗k−x15∗k+x22∗k……)
n*sqrt(n)求出G后,每次询问再用sqrt(n/k)的时间求得G’(n)即可。