普通母函数笔记

定义

在数学中,某个序列的母函数(Generating function,又称生成函数)是一种形式幂级数,其每一项的系数可以提供关于这个序列的信息。使用母函数解决问题的方法称为母函数方法。
在这里插入图片描述

详解

以下内容参考Tonyyy的博客。
首先举一个经典的例子。

现有质量为1, 2, 3的砝码各一枚,问:
(1)可以称出多少种不同质量的物品。
(2)要称出质量为3的物品,有多少种方案。

解:
在数字逻辑中我们使用 + 代表或逻辑,* 代表与逻辑,这里我们同样的含义。

(使用1g+不适用1g) * (使用2g+不适用2g) = (使1 * 使2) + (使1 * 不使2) + (不使1 * 使2) + (不使1 * 不使2)

通过上面可以看到逻辑运算和我们普通算数的多项式计算是相似的。那我们可不可以把这样一个逻辑运算使用多项式表达出来呢?**再回到题目,最后的两个砝码的计算实际是一个加法运算,那么有没有这样一个运算是乘法变加法。不难想到幂乘,xm * xn = xm+n。**这样就使用幂次当作质量,因此1g的砝码可以写为 (x0 + x1) = (1 + x1),其中x0的零次方就代表了不使用质量为1的砝码。

(1)这样的话答案就变为了(1+x) * (1+x2) * (1+x3) = 1 + x + x2 + 2x3 + x4 + x5 + x6
上面我们定义是x的幂次代表质量,因此,共可以称6种质量的物品,分别是从1——6g。

(2)x3前面的系数为2,因此有两种方法可以称出质量为3的物品。

如果三个砝码的数量是无限的,那么1g就可以表示为(1+x1 + x2…+xn),代表可以称的质量,2g表示为(1 + x2 + x4 + x6 + …x+x2n)。
因此构造的母函数就变为了G(x) = (1 + x + x2…)(1 + x2 + x4…)(1+x3 + x6…)…

例题

例题一

hdu-找单词

题解

通过上面的证明我们可以直接构造出来母函数,G(x) = (1+x+x2+x3 +…+xx1)(1+x2 + x4 + x6 +…+x2x2)…(1 + x + x26 + x52 +…+x26x26)
母函数有了就可以直接通过一个递推来求解每个多项式乘后的结果,由于题目要求价值不大于50,因此我们只需要计算到x50即可。

ac代码

#include <iostream>
#include <cstring>

using namespace std;

int main()
{
    int a[60], b[60];
    int n;
    
    scanf("%d", &n);
    
    while (n--)   //n个样例
    {
        int num;
        
        memset(a, 0, sizeof(a));
        memset(b, 0, sizeof(b));
        a[0] = 1;
        
        for (int i=1; i<=26; i++)   //总共输入26个字母的个数
        {
            scanf("%d", &num);
            
            for (int j=0; j<=50; j++)   //这里就是进行多项式模拟,可以在纸上推一下
            {
                for (int k=0; k<=num && k*i+j<=50; k++) //k表示第j个指数,所以k每次增加i
                {
                    b[k*i+j] += a[j];
                }
            }
            
            for (int j=0; j<=50; j++)
            {
                a[j] = b[j];
                b[j] = 0;
            }
        }
        
        int total = 0;
        
        for (int i=1; i<=50; i++)
            total += a[i];
            
        printf("%d\n", total);
    }
    
    return 0;
}

例题二

hdu1028

题目大意

给你一个整数,问你有多少种拆分方法。

解题思路

这个题和上面的母函数题其实是一样的,上面的是给定质量的砝码,本题的砝码只不过从给定的变为了1-n了,并且数量是没有要求的,只要总质量等于n即可。
因此构造出来的母函数和上一个题大同小异,G(x) = (1 + x 1 + x2 +…xn)(1 + x2 + x4 …+xn/2)(1 + x3 + x6 +…+xn/3)…(1 + xn)

ac代码

#include <iostream>
#include <cstring>

using namespace std;

int main()
{
    int a[121], b[121];
    int n;
    
    while (~scanf("%d", &n))
    {
        memset(a, 0, sizeof(a));
        memset(b, 0, sizeof(b));
        
        a[0] = 1;
        
        for (int i=1; i<=n; i++)
        {
            for (int j=0; j<=n; j++)
            {
                for (int k=0; k+j<=n; k+=i)
                {
                    b[k+j] += a[j];
                }
            }
            
            for (int j=0; j<=n; j++)
            {
                a[j] = b[j];
                b[j] = 0;
            }
        }
        
        printf("%d\n", a[n]);
    }
    
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值