现在的位置: 首页 > 综合 > 正文

生成函数(母函数)

2017年10月18日 ⁄ 综合 ⁄ 共 3146字 ⁄ 字号 评论关闭

         

               看了一个下午的生成函数(又称母函数),初次理解,于是便总结一下。

 

              生成函数是说,构造一个多项式函数 g(x) ,是的 x  的n 次方 的系数是 f(n) .

 

              即: ~g(x) = 1 + f(1) * x^1 + f(2) * x^2 + f(3) * x^3 + .......+f(k) * x^k + ........

 

               这里的 g(x) 就是一个生成函数。

      

              那么 f(n)  的含义呢?

 

             这个函数的话,就是由你自己构造了。

 

             如何构造呢?下面由一个例题,来引出:

 

            用1,2,3来组成不同的值。而我们要求的就是给定一个n,有多少种组成的方法。

 

             这里我们用到生成函数来解这题。

 

              要用到生成函数就一定先要知道 f(n)  这个函数。

 

              我们先来看这个问题,一个数 n  能用 1 组成的方法有多少种呢?  答案很明显,1种。

 

               也就是说如果我们上面说的那个问题变成: 用 1 来组成不同的值,我们要求给定一个n ,有多少种组成的方法。

 

              这样,这个问题是不是变得很简单了,只要不是脑残,应该都能一眼看出答案,1种,不管n 是多少,都是一种。

 

              那么我们的 f(n) 也就出来了。

 

             即: f(1)=1

                       f(2)=1

                       f(3)=1 

                       f(4)=1 

                       f(5)=1

                          ......

                       f(n)=1

 

             很容易就可以看出这个f()函数的意义,即n代表一个值,而f(n)的值表示用 1 组成 n的方法的个数。

 

             既然f(n) 出来了,那么它的构造函数当然也出来了。

 

           即:~g(x)=1+x^1+x^2+x^3+.........+x^k+.....x^n+.......

 

              到这里,不着急,我们继续看,

 

             刚才我们是用 1 来组成一个给定的任意值 n ,求组成的方法数。

 

             现在我们继续转化,我们用 2 来组成一个给定的任意值 n, 求组成的方法数。

 

              因为用2来组成的数一定都是偶数,而且组成的方法数也一定都是一种,所以

 

             我们根据 f() 函数的定义,可以知道 f(n) 的值:

                  

                       f(1)=0 

                       f(2)=1 

                       f(3)=0 

                       f(4)=1 

                       f(5)=0

                         ......

              这个的含义也和前一个问题的 f() 函数一样,那么我们的构造函数也能出来了。

 

              即:~g(x)=1 + x^2 +x^4 +x^6+.......

 

                 同理我们也就可以推出,当用 3 来组成 n 时的 f()函数,以及生成函数。

 

                 那么接下来我们推广一下,我们将原来的 1 啊,2 啊, 3啊,等一个个的数,都看成是一个个的集合,即{1},{2},{3}

 

                而我们的问题就是要用集合的里的数,来组成一个数值 n,求组成的方法数。

 

               原先集合里都只有1个元素,所以我们能很快得出 f (n) 答案,但是当有多个元素时,这个问题,就变成了,我们最开始要求的那个问题了。

 

               如何用1,2,3来组成一个数值 n,求组成的方法数。

 

                这里的集合就是{1,2,3}

 

               而结果如何求呢?

 

                因为我们已经计算出了,单个元素的 f() 函数,所以我们求此时的集合所对应的 f() 函数时,就要用到构造函数。

 

                 我们将每个元素的构造函数都乘起来,得到的这个函数,就是我们现在的集合所对应的生成函数了。

 

              即:g(x)=(1+x^1+x^2+.....) (1 + x^2 +x^4 +......) (1 + x^3 +x^6+ .......)

 

                我们展开函数,使之成为

 

                g(x) = 1 + f(1) * x^1 + f(2) * x^2 + f(3) * x^3 + .......+f(k) * x^k + ........

 

                 然后我们要求的结果也就出来了。就是 f(n) 。即:用{1,2,3}组成 n 的方法数有 f(n) 种。

 

                先暂时说到这里吧,下面贴一下,这个简单代码(引用的哦):

 

#include <iostream>
using namespace std;
// Author: Tanky Woo
// www.wutianqi.com
const int _max = 10001; 
// c1是保存各项质量砝码可以组合的数目
// c2是中间量,保存没一次的情况
int c1[_max], c2[_max];   
int main()
{	//int n,i,j,k;
	int nNum;   // 
	int i, j, k;
 
	while(cin >> nNum)
	{
		for(i=0; i<=nNum; ++i)   // ---- ①
		{
			c1[i] = 1;
			c2[i] = 0;
		}
		for(i=2; i<=nNum; ++i)   // ----- ②
		{
 
			for(j=0; j<=nNum; ++j)   // ----- ③
				for(k=0; k+j<=nNum; k+=i)  // ---- ④
				{
					c2[j+k] += c1[j];
				}
			for(j=0; j<=nNum; ++j)     // ---- ⑤
			{
				c1[j] = c2[j];
				c2[j] = 0;
			}
		}
		cout << c1[nNum] << endl;
	}
	return 0;
}

 

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

①  、首先对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每次是从一个表达式中开始的。

 

 

来源:http://www.wutianqi.com/?p=596   (母函数详解)

 

以后再接触,再继续更改。

 

 

 

 

 

 

抱歉!评论已关闭.