Skip to content

Latest commit

 

History

History

1735.Count-Ways-to-Make-Array-With-Product

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

1735.Count-Ways-to-Make-Array-With-Product

一个比较粗暴的方法就是递归。对于k,我们遍历它的因数x1,然后遍历k/x1的因数x2,然后遍历k/x1/x2的因数x3,...,直至遍历完所有的n个因数。因为n很大可以达到1000,这个递归深度就太深了,一定会TLE。

有什么高效的方法来把k分解成n组因数的乘积呢?我们自然会想到质因数。比如说12=2x2x3,想要将其分割为4组的话,就是把这三个质因数分成4组(允许某组为空,也就是该组所对应的因数是1)。对于把x个同质球分成y份的方法数,是一个经典的组合问题,答案就是组合数C(x+y-1, y-1)。我们可以这么理解:将x+y个“虚拟球”排成一列,中间就有x+y-1个间隔,我们在其中选择y-1个间隔插入板子,就可以得到y个区间,每一个区间至少有一个“虚拟球”。我们约定:插板后每段区间内“虚拟球”的数目减去一,就是该区间分组的真实球的数量。我们可以想象,每一个合法的插板方法,都恰好一一映射了一种合法的“将x个同质球分成y份(允许某份为零)”的方案。

比如说将2x2x3这3个质因数分为4份,插板方案有

    插板               每组元素个数  分解方案
O | O O | O | O O O =>  0 1 0 2 => 1x2x1x6
O | O O | O O | O O =>  0 1 1 1 => 1x2x2x3
O | O O O | O O | O =>  0 2 1 0 => 1x4x3x1
O O | O | O | O O O =>  1 0 0 2 => 2x1x1x6
O O | O | O O | O O =>  1 0 1 1 => 2x1x2x3
O O | O  O | O O |O =>  1 1 1 0 => 2x2x3x1
...

总共有C(6,3)=6种方案。

但是以上方案有个问题,就是没有考虑到这3个质因数(2,2,3)的permutation。我们似乎得找出所有unique permuation,然后对每种permutation都用上面的插板法来分组。

那么如何解决呢?方法是对于每个质因数apply上述的分组方案。比如说12,它的质因数2出现了两次,那么我们就考虑如何把这两个2分成4组;它的质因数3出现了一次,我们就考虑如何把这一个3分成4组。这样,对于相同的质因数,它如果有x个,那么这x个元素就是“同质球”,彼此之间是没有区别的,我们就可以放心地应用插板法。

最终的方案总数的计算法方法。分解质因数k = x1^p1 + x2^p2 + x3^p3 + ... 总方案数 = 把p1个(相同质因数x1)分成n组方案 * 把p2个(相同质因数x2)分n组方案 * 把p3个(相同质因数x3)分成n组方案 ...