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

母函数可分为很多种,包括普通母函数、指数母函数、L级数、贝尔级数和狄利克雷级数。对每个序列都可以写出以上每个类型的一个母函数。构造母函数的目的一般是为了解决某个特定的问题,因此选用何种母函数视乎序列本身的特性和问题的类型。

这里先给出两句话,不懂的可以等看完这篇文章再回过头来看:

1.“把组合问题的加法法则和幂级数的乘幂对应起来”

2.“母函数的思想很简单 — 就是把离散数列和幂级数一 一对应起来,把离散数列间的相互结合关系对应成为幂级数间的运算关系,最后由幂级数形式来确定离散数列的构造. “

我们首先来看下这个多项式乘法:

母函数图(1)

由此可以看出:

1.x的系数是a1,a2,…an 的单个组合的全体。

2. x^2的系数是a1,a2,…a2的两个组合的全体。

………

n. x^n的系数是a1,a2,….an的n个组合的全体(只有1个)。

进一步得到:

母函数图(2)

母函数的定义

对于序列a0,a1,a2,…构造一函数:

母函数图(3)

称函数G(x)是序列a0,a1,a2,…的母函数。

这里先给出2个例子,等会再结合题目分析:

第一种:

有1克、2克、3克、4克的砝码各一枚,能称出哪几种重量?每种重量各有几种可能方案?

考虑用母函数来解决这个问题:

我们假设x表示砝码,x的指数表示砝码的重量,这样:

1个1克的砝码可以用函数1+1*x^1表示,

1个2克的砝码可以用函数1+1*x^2表示,

1个3克的砝码可以用函数1+1*x^3表示,

1个4克的砝码可以用函数1+1*x^4表示,

上面这四个式子懂吗?

我们拿1+x^2来说,前面已经说过,x表示砝码,x的指数表示砝码的重量!初始状态时,这里就是一个质量为2的砝码。

那么前面的1表示什么?按照上面的理解,1其实应该写为:1*x^0,即1代表重量为2的砝码数量为0个。

所以这里1+1*x^2 = 1*x^0 + 1*x^2,即表示2克的砝码有两种状态,不取或取,不取则为1*x^0,取则为1*x^2

不知道大家理解没,我们这里结合前面那句话:

“把组合问题的加法法则和幂级数的乘幂对应起来“

接着讨论上面的1+x^2,这里x前面的系数有什么意义?

这里的系数表示状态数(方案数)

1+x^2,也就是1*x^0 + 1*x^2,也就是上面说的不取2克砝码,此时有1种状态;或者取2克砝码,此时也有1种状态。(分析!)

所以,前面说的那句话的意义大家可以理解了吧?

几种砝码的组合可以称重的情况,可以用以上几个函数的乘积表示:

(1+x)(1+x^2)(1+x^3)(1+x^4)

=(1+x+x^2+x^4)(1+x^3+^4+x^7)

=1 + x + x^2 + 2*x^3 + 2*x^4 + 2*x^5 + 2*x^6 + 2*x^7 + x^8 + x^9 + x^10

从上面的函数知道:可称出从1克到10克,系数便是方案数。(!!!经典!!!)

例如右端有2^x^5 项,即称出5克的方案有2种:5=3+2=4+1;同样,6=1+2+3=4+2;10=1+2+3+4。

故称出6克的方案数有2种,称出10克的方案数有1种 。


接着上面,接下来是第二种情况:

第二种:

求用1分、2分、3分的邮票贴出不同数值的方案数:

大家把这种情况和第一种比较有何区别?第一种每种是一个,而这里每种是无限的。

母函数图(4)

以展开后的x^4为例,其系数为4,即4拆分成1、2、3之和的拆分方案数为4;

即 :4=1+1+1+1=1+1+2=1+3=2+2

这里再引出两个概念"整数拆分"和"拆分数":

所谓整数拆分即把整数分解成若干整数的和(相当于把n个无区别的球放到n个无标志的盒子,盒子允许空,也允许放多于一个球)。

整数拆分成若干整数的和,办法不一,不同拆分法的总数叫做拆分数。

现在以上面的第二种情况每种种类个数无限为例,给出模板:

[cpp] view plaincopy
  1. #include <iostream>
  2. using namespace std;
  3. // Author: Tanky Woo
  4. // www.wutianqi.com
  5. const int _max = 10001;
  6. // c1是保存各项质量砝码可以组合的数目
  7. // c2是中间量,保存每一次的情况
  8. int c1[_max], c2[_max];
  9. int main()
  10. {   //int n,i,j,k;
  11. int nNum;   //
  12. int i, j, k;
  13. while(cin >> nNum)
  14. {
  15. for(i=0; i<=nNum; ++i)   // ---- ①
  16. {
  17. c1[i] = 1;
  18. c2[i] = 0;
  19. }
  20. for(i=2; i<=nNum; ++i)   // ----- ②
  21. {
  22. for(j=0; j<=nNum; ++j)   // ----- ③
  23. for(k=0; k+j<=nNum; k+=i)  // ---- ④
  24. {
  25. c2[j+k] += c1[j];
  26. }
  27. for(j=0; j<=nNum; ++j)     // ---- ⑤
  28. {
  29. c1[j] = c2[j];
  30. c2[j] = 0;
  31. }
  32. }
  33. cout << c1[nNum] << endl;
  34. }
  35. return 0;
  36. }

我们来解释下上面标志的各个地方:(***********!!!重点!!!***********)

①  、首先对c1初始化,由第一个表达式(1+x+x^2+..x^n)初始化,把质量从0到n的所有砝码都初始化为1.

②  、 i从2到n遍历,这里i就是指第i个表达式,上面给出的第二种母函数关系式里,每一个括号括起来的就是一个表达式。

③、j 从0到n遍历,这里j就是(前面i個表达式累乘的表达式)里第j个变量,(这里感谢一下seagg朋友给我指出的错误,大家可以看下留言处的讨论)。如(1+x)(1+x^2)(1+x^3),j先指示的是1和x的系数,i=2执行完之后变为

(1+x+x^2+x^3)(1+x^3),这时候j应该指示的是合并后的第一个括号的四个变量的系数。

④ 、 k表示的是第j个指数,所以k每次增i(因为第i个表达式的增量是i)。

⑤  、把c2的值赋给c1,而把c2初始化为0,因为c2每次是从一个表达式中开始的。


咱们赶快趁热打铁,来几道题目:

(相应题目解析均在相应的代码里分析)

1.  题目:http://acm.hdu.edu.cn/showproblem.php?pid=1028

代码:http://www.wutianqi.com/?p=587

这题大家看看简单不?把上面的模板理解了,这题就是小Case!

看看这题:

2.  题目:http://acm.hdu.edu.cn/showproblem.php?pid=1398

代码:http://www.wutianqi.com/?p=590

要说和前一题的区别,就只需要改2个地方。 在i遍历表达式时(可以参考我的资料—《母函数详解》),把i<=nNum改成了i*i<=nNum,其次在k遍历指数时把k+=i变成了k+=i*i; Ok,说来说去还是套模板~~~

3.  题目:http://acm.hdu.edu.cn/showproblem.php?pid=1085

代码:http://www.wutianqi.com/?p=592

这题终于变化了一点,但是万变不离其中。

大家好好分析下,结合代码就会懂了。

4.  题目:http://acm.hdu.edu.cn/showproblem.php?pid=1171

代码:http://www.wutianqi.com/?p=594

还有一些题目,大家有时间自己做做:

HDOJ:1709,1028、1709、1085、1171、1398、2069、2152

(原创文章,欢迎各位转载,但是请不要任意删除文章中链接,请自觉尊重文章版权,违法必究,谢谢合作。Tanky Woo原创, www.WuTianQi.com)

附:

1.在维基百科里讲到了普通母函數、指數母函數、L級數、貝爾級數和狄利克雷級數:

http://zh.wikipedia.org/zh-tw/%E6%AF%8D%E5%87%BD%E6%95%B0

2.Matrix67大牛那有篇文章:什么是生成函数:

http://www.matrix67.com/blog/archives/120

3.大家可以看看杭电的ACM课件的母函数那篇,我这里的图片以及一些内容都引至那。


如果大家有问题或者资料里的内容有错误,可以留言给出,博客: http://www.wutianqi.com/

Tanky Woo原创文章,转载请注明出处:http://www.wutianqi.com/?p=596。

对于任何转载本博客文章且不保留原文链接或任意删改文中链接的行为,本人将一定周旋到底!

母函数 入门 + 模板相关推荐

  1. dp 母函数 入门 + 模板

    dp 母函数 入门 + 模板 在数学中,某个序列的母函数(Generating function,又称生成函数)是一种形式幂级数,其每一项的系数可以提供关于这个序列的信息.使用母函数解决问题的方法称为 ...

  2. unity入门_探索Unity MARS入门模板

    unity入门 Starter Templates are predesigned, customizable building blocks created to help AR developer ...

  3. 生成函数(母函数)入门详解

    感谢大佬! 感谢大佬 本文章从以上两位大佬的博客参考而来!再次感谢! 母函数,又称生成函数,是ACM竞赛中经常使用的一种解题算法,常用来解决组合方面的题目. 在数学中,某个序列的母函数(Generat ...

  4. FatMouse and Cheese HDU - 1078(记忆化搜索入门模板)

    题意: n * n的正方形格子(每个格子均放了奶酪),老鼠从(0,0)开始,每次最多移动k步,可以选择上下左右四个方向移动,下一个移动点奶酪块数量必须要大于当前点. 整理模板ing- 题目: FatM ...

  5. 51单片机入门模板(STC89C52RC)

    该模板适用于51单片机入门,比较易于理解,包含定时器和串口的操作. 可以在定时器T0中断服务函数和主循环中实现主要功能,在UART中断服务函数(T1定时器)中实现简单的串口通信接收命令的功能. 注:本 ...

  6. hdu 1028 Ignatius and the Princess III 母函数入门

    传送门 文章目录 题意: 思路: 题意: 给你一个数nnn,问你有多少种方案用1−n1-n1−n的数能组成nnn,数的使用次数无限制. n≤120n\le120n≤120 思路: 考虑构造母函数. 对 ...

  7. HDU - 1028——母函数入门

    [题目描述] "Well, it seems the first problem is too easy. I will let you know how foolish you are l ...

  8. Express入门 模板引擎hbs 服务端渲染

    Express支持多种模板引擎,这里将采用Handlebars模板引擎的服务器端版本hbs模板引擎 . 安装hbs npm install hbs --save-dev 安装hbs模板引擎后改写app ...

  9. html怎么转换成ftl模板,FreeMarker入门+模板静态化+模板字符串静态化

    只是根据模板的内容,将数据模型在模板中显示并输出文件(通常为html,也可以生成其它格式的文本文件) 数据模型:数据模型在java中可以是基本类型也可以List.Map.Pojo等复杂类型 模板 输出 ...

最新文章

  1. Mysql CPU占用高的问题解决方法小结
  2. 类对象和类指针深入分析与对比
  3. H3CNE新版本V6.0与旧版本V5.1的区别
  4. 数据库考研SQL操作
  5. java注释的理解,java注解原理——记录一下自己的理解
  6. nxos启动的初始化和https访问nx-api
  7. 哦,指针问题的见解啊
  8. java之xml编程
  9. 我和谷歌共同成长----Andriod(安卓)开发(持续更新)
  10. CMD 打开各个浏览器命令
  11. 【实践与问题解决38】win10桌面图标变成一个空白图标
  12. ARMv7 KVM 在 linux中的实现 3 内存角度
  13. Java8 拉姆达与集合中对象处理方式记录
  14. 无监督低照度图像增强网络ZeroDCE和SCI介绍
  15. Linux 下的 3D 设计软件-FreeCAD
  16. jQuary中delegate()函数的作用
  17. 编译原理——词法分析(1)
  18. 服务器 网站流量监控,网站服务器流量监控工具
  19. harbor企业级镜像仓库搭建
  20. mipcms文章列表调用

热门文章

  1. js前端——滑稽官网的亮瞎眼系列滑稽大法
  2. 大数——大数阶乘(hdu1042)
  3. tcp retransmission原因
  4. git 命令之 如何将本地新建分支推到服务器上
  5. Word文档显示标题3
  6. mysql 修改密码演练
  7. 工具栏的使用 1118
  8. git-创建版本仓库-创建版本-查看版本
  9. python-if判断的本质
  10. django-编辑学生