1. 程式人生 > >整數劃分問題的高效解法 (n logn)

整數劃分問題的高效解法 (n logn)

一般此類問題可以看做是一個揹包問題,不過有更優秀的解法。

1.數字互不相同(51nod1201)(O(nn))

注意到最多有O(n)個數相加,則記fi,j表示j個數和為i的方案數。我們討論一個方案的最小值是否為1,如果為1,則fi1,j1fi,j,否則我們把每一個數減去1,fij,jfi,j

即:fi,j=fij,j1+fij,j, 時間複雜度

Code

2.數字可以重複 (51nod1259)(O(nn)/O
(nlogn)
)

O(nn)解法

注意到n的數最多出現n次,那我們分開做。
前面做揹包,後面同樣考慮最小的數,若為n那麼fiB,j1fi,j,否則fij,jfi,j
時間複雜度為O(nn)
Code

O(nlogn)解法

利用分拆數和五邊形數的關係,我們得到一個卷積遞推式。
fg=f1f=11g
其中g3k2±k2=(1)k+1
(modxn+1)意義下做多項式求逆即可,時間複雜度

O(nlogn)
(為了方便,這裡對998244353取模,對於任意模數可以考慮實數FFT或者三模數NTT,由於常數較大這裡跳過)。
Code
也可以直接遞推,易知複雜度為O(nn)