母函数及其应用+模板

部分摘自这位大佬的博客https://www.cnblogs.com/linyujun/p/5207730.html

生成函数即母函数,是组合数学中尤其是计数方面的一个重要理论和工具。 最早提出母函数的人是法国数学家LaplaceP.S.在其1812年出版的《概率的分析理论》中明确提出“生成函数的计算”。 生成函数的应用简单来说在于研究未知(通项)数列规律,用这种方法在给出递推式的情况下求出数列的通项。

在这里我们不去高深地研究数学上母函数,而是讲讲简单的母函数应用。

1.母函数引入

就是把一个已知的序列和x的多项式合并起来,新产生的多项式就叫原来序列的母函数

序列{0,1,2,3,4,5...n}的母函数就是

f(x)=0+x+2x^2+3x^3+4x^4+...+nx^n(这个x没有任何意义,应该说,你不需要把它当做一个函数,你只要知道母函数这么写就可以了)

序列{1,1,1,1,1......}的母函数就是

f(x)=1+x+x^2+x^3+x^4....

二项式展开的序列比如这个{1,4,6,4,1,0,0,0,0,0.....}是C(4,0)到C(4,4)的系数,那它的母函数就是

f(x)=1+4x+6x^2+4x^3+1x^4

这些东西对于我们来说并没有说明意义,母函数对我们来说只是一个工具,是一个载体,那来看看母函数是怎么样装载数据的吧!

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

假如x的指数表示砝码

那么

1克的砝码表示为1+x^1

2克的砝码表示为1+x^2

3克的砝码表示为1+x^3

4克的砝码表示为1+x^4

每个砝码都可以选择取或不取

所以这里的1可以认为1*x^0,表示不取这颗砝码

那么把这些乘起来

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

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

根据指数来看,我们可以称出0~10这么多的重量,其中3~7的系数为2,说明有2种称的方法

那么我们来细看一遍

0:(什么砝码都不放).......................(1种)

1:1.............................................(1种)

2:2.............................................(1种)

3:3或1+2.....................................(2种)

4:4或1+3.....................................(2种)

5:1+4或2+3.................................(2种)

6:2+4或1+2+3..............................(2种)

7:3+4或1+2+4..............................(2种)

8:1+3+4......................................(1种)

9:2+3+4......................................(1种)

10:1+2+3+4.................................(1种)

分毫不差

所以说母函数在ACM就是这么用的,跟函数没关系,跟写法有关系。

例2:求用1分、2分、3分的邮票贴出不同数值的方案数,每种邮票可以有无限张。

因邮票允许重复,故母函数为:

对于这种连续相乘,我们人类是很讨厌的,但对于计算机这种重复运算是很轻松的,我们只要将我们解多项式的思路带进去即可。

2.代码说明

我们首先知道对于最后得到的那一个母函数,系数代表的是方案数,而指数代表的是组成的数值,运算过程就是多项式的乘法。而两个多次方程的乘法,运算无非是系数相乘,指数相加,仅仅是这个方程的这么两个信息的运算。那能不能用什么数据结构直接表示出一个对象的这个两个信息呢?首先想到的可能是结构体,结构体可以用来表示一个对象的多个信息,但是运算繁琐;其实用数组就可以了,下标代表组成的数组,数值代表方案数!!!

a.求用1分、2分、3分的邮票贴出不同数值的方案数:(每张邮票的数量是无限的)

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #define MAX 310
 6 int a[MAX];///最终合并的多项式
 7 int b[MAX];///临时合并用的多项式
 8 int n;
 9 const int N=110;
10 using namespace std;
11 void init()
12 {
13     int i,j,k;
14     a[0]=1;///一开始的0的情况
15     for (i=1; i<=3; i++)///代表1分,2分,3分三个多项式的合并
16     {
17         for (j=0; j<N; j+=i)///i分的邮票,步长为i
18         {
19             for (k=0; k+j<N; k++)///从x^0到x^N遍历一遍
20             {
21                 b[j+k]+=a[j];///核心
22             }
23         }
24         for (j=0; j<N; j++)///b中数据抄到a,b清空
25         {
26             a[j]=b[j];
27             b[j]=0;
28         }
29     }
30 }
31 int main()
32 {
33     int i,j,k;
34     init();
35     while(scanf("%d",&n)!=EOF)
36     {
37         printf("%d\n",a[n]);
38     }
39     return 0;
40 }

b.hdu 1028

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

题目问一个数字n能够拆成多少种数字的和

比如n=4

4 = 4;
  4 = 3 + 1;
  4 = 2 + 2;
  4 = 2 + 1 + 1;
  4 = 1 + 1 + 1 + 1;

有5种,那么答案就是5

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #define MAX 130
 6 #define N 130
 7 #define ll long long int
 8 ll a[MAX];
 9 ll b[MAX];
10 int n;
11 using namespace std;
12 void init()
13 {
14     int i,j,k;
15     a[0]=1;
16     for (i=1; i<=MAX; i++)
17     {
18         for (j=0; j<N; j+=i)
19         {
20             for (k=0; k+j<N; k++)
21             {
22                 b[j+k]+=a[k];
23             }
24         }
25         for (j=0; j<N; j++)
26         {
27             a[j]=b[j];
28             b[j]=0;
29         }
30     }
31 }
32 int main()
33 {
34     init();
35     while(scanf("%d",&n)!=EOF)
36     {
37         printf("%lld\n",a[n]);
38     }
39     return 0;
40 }

 

c.hdu 1398

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

题目说一个国家的硬币都是方形的,面值也是方形的

有1块钱,4块钱,9块钱,16块钱......一直到289块钱(17^2)

问想组成n块钱有几种方法

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #define ll long long int
 6 #define MAX 17
 7 #define N 305
 8 using namespace std;
 9 ll a[N];
10 ll b[N];
11 void init()
12 {
13     int i,j,k;
14     a[0]=1;
15     for (i=1; i<=MAX; i++)
16     {
17         for (j=0; j<N; j+=i*i)
18         {
19             for (k=0; k+j<N; k++)
20             {
21                 b[j+k]+=a[k];
22             }
23         }
24         for (j=0; j<N; j++)
25         {
26             a[j]=b[j];
27             b[j]=0;
28         }
29     }
30 }
31 int main()
32 {
33     int n;
34     init();
35     while(scanf("%d",&n)!=EOF)
36     {
37         if(n==0)
38         {
39             break;
40         }
41         printf("%lld\n",a[n]);
42     }
43     return 0;
44 }

原文地址:https://www.cnblogs.com/wkfvawl/p/9741001.html

时间: 2024-10-15 12:46:44

母函数及其应用+模板的相关文章

母函数的基本模板讲解

母函数的基本代码模板 自己理解:对于(#式)  (1+x+x^2+x^3+x^4+x^5+....)*(1+x^2+x^4+x^6+x^8+x^10+....)*(1+x^3+x^6+x^9+x^12....)..... 第一个for给c1 和 c2 赋值 , 把上面#式的第一个括号(1+x+x^2+x^3+x^4+x^5+....)的系数给放在c1中, 从而再次计算从 # 的 第二个括号开始 , 所以 i 就是代表的# 式第几个括号, 而 用程序模拟手工计算 , 就是 先计算第一个括号 与 第

组合数学 - 母函数的运用 --- 模板题

Holding Bin-Laden Captive! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 15064    Accepted Submission(s): 6750 Problem Description We all know that Bin-Laden is a notorious terrorist, and he h

组合数学 - 母函数的运用 + 模板 --- hdu : 2082

找单词 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4093    Accepted Submission(s): 2933 Problem Description 假设有x1个字母A, x2个字母B,..... x26个字母Z,同时假设字母A的价值为1,字母B的价值为2,..... 字母Z的价值为26.那么,对于给定的字母,可以找到

母函数入门【模板】

正整数拆分 hdu1028 解: 对于正整数 $n$ 的拆分,其母函数为 $$f(x) = (1+x+x^2+...)(1+x^2+x^4+...)(1+x^3+x^6+x^9+...)...$$ 答案就是多项式展开后 $x^n$ 项的系数. Code: //其实就是模拟,从前往后一一合并 #include<bits/stdc++.h> using namespace std; const int _max = 10001; int c1[_max], c2[_max]; //c1存放前面项计

hdu 2079

选课时间(题目已修改,注意读题) Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3222    Accepted Submission(s): 2525 Problem Description 又到了选课的时间了,xhd看着选课表发呆,为了想让下一学期好过点,他想知道学n个学分共有多少组合.你来帮帮他吧.(xhd认为一样学分的课没区别

母函数入门+模板(转)

在数学中,某个序列的母函数(Generating function,又称生成函数)是一种形式幂级数,其每一项的系数可以提供关于这个序列的信息.使用母函数解决问题的方法称为母函数方法. 母函数可分为很多种,包括普通母函数.指数母函数.L级数.贝尔级数和狄利克雷级数.对每个序列都可以写出以上每个类型的一个母函数.构造母函数的目的一般是为了解决某个特定的问题,因此选用何种母函数视乎序列本身的特性和问题的类型. 这里先给出两句话,不懂的可以等看完这篇文章再回过头来看: 1.“把组合问题的加法法则和幂级数

Square Coins (HDU 1398) ———母函数模板详解

Square Coins Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7748    Accepted Submission(s): 5238 Problem Description People in Silverland use square coins. Not only they have square shapes but

母函数 入门 + 模板

转自:母函数 入门 + 模板  感谢 在数学中,某个序列的母函数(Generating function,又称生成函数)是一种形式幂级数,其每一项的系数可以提供关于这个序列的信息.使用母函数解决问题的方法称为母函数方法. 母函数可分为很多种,包括普通母函数.指数母函数.L级数.贝尔级数和狄利克雷级数.对每个序列都可以写出以上每个类型的一个母函数.构造母函数的目的一般是为了解决某个特定的问题,因此选用何种母函数视乎序列本身的特性和问题的类型. 这里先给出两句话,不懂的可以等看完这篇文章再回过头来看

HDU1398 Square Coins 【母函数模板】

Square Coins Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7995    Accepted Submission(s): 5416 Problem Description People in Silverland use square coins. Not only they have square shapes but