母函数(思想而非套路)

普通母函数:

可以用来求解一些组合数问题,例如最经典的x中砝码可以构成重量为y方案数有多少?

普通的话穷举所有的方案数是2^n的复杂度,指数级增长很快

但是利用母函数的话,可以转换成一个幂级数的乘积的形式,转换方案见代码,可以将复杂度降低到n^3,是一个幂级数复杂度,远低于指数级复杂度

题目如下:

/*
普通母函数:将离散数列的构造简化为幂级数
例子:现在1g 3g 5g 9g 的砝码各有无限个,问构成13g的方案数有多少
我们知道1g的可以选择1个,2个,3个...13个  我们用x1 x2 x3...x13代表
        3g的可以选择1个,2个,3个,4个,我们用x3 x6 x9 x12代表
5g 9g 同理
下角标代表的是重量  前面的标号就是方案数
于是我们可以列出来算式就是(x1+x2+x3+x4+..+x13)*(x3+x6+x9+x12)*(x5+x10)*(x9)=...=a*x2+b*x5=a*b*x7
之后求13的方案数就是x13的系数
为什么称之为母函数呢 实际上是一种思想
就是一种将离线序列转换为幂级数的方案
*/
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>

using namespace std;

int maxx;
int n;
int a[100];
int sug[100];  ///保存每个值的系数
int tmp[100];  ///保存临时结果

int main()
{
    while( scanf("%d" , &n)!=EOF )
    {
        scanf("%d" , &maxx);
        for(int i=1; i<=n; i++)
        {
            scanf("%d" , &a[i]);
        }
        memset(tmp , 0 , sizeof(tmp));
        for(int i=0; i<=maxx; i+=a[1])   ///从0开始因为可以不选这个
        {
            sug[i] = 1;
        }
        for(int i=2; i<=n; i++)
        {
            for(int j=1; j<=maxx; j++)
            {
                for(int k=0; k<=maxx; k+=a[i])
                {
                    tmp[j+k] += sug[j]*1;
                }
            }
            for(int j=1; j<=maxx; j++)
            {
                sug[j] = tmp[j];
                tmp[j] = 0;
            }
        }
        for(int i=1; i<=maxx; i++)
            printf("%d..%d..
" , i , sug[i]);   ///输出组成每种重量的方案数
    }




    return 0;
}

指数型母函数:

用来求解多重集的排列问题


指数型母函数:(用来求解多重集的排列问题)

    n个元素,其中a1,a2,····,an互不相同,进行全排列,可得n!个不同的排列。

    若其中某一元素ai重复了ni次,全排列出来必有重复元素,其中真正不同的排列数应为 ,即其重复度为ni!

    同理a1重复了n1次,a2重复了n2次,····,ak重复了nk次,n1+n2+····+nk=n。

    对于这样的n个元素进行全排列,可得不同排列的个数实际上是 

    若只对其中的r个元素进行排列呢,那就用到了指数型母函数。

    构造母函数G(x)=+则称G(x)是数列a0,a1…an的指数型母函数。

    一般过程:

        1.建立模型:物品n种,每种数量分别为k1,k2,..kn个,求从中选出m个物品的排列方法数。

        2.构造母函数:G(x)=(1+ + …+)(1+ ++…)…(1+ ++…)

                                    =a0+a1·x+  ·  + · +… ·  (其中pp=k1+k2+k3…kn)

                          G(x)含义:ai为选出i个物品的排列方法数。

           若题中有限定条件,只要把第i项出现的列在第i项的式中,未出现的不用列入式中。

           如:物品i出现的次数为非0偶数,则原式改为…*(    +  +     )*…



感谢:https://blog.csdn.net/yu121380/article/details/79914529

原文地址:https://www.cnblogs.com/Flower-Z/p/10111115.html