• 母函数细致讲解


    母函数又称生成函数。定义是给出序列:a0,a1,a2,.......ak,......,那么函数G(x)=a0+a1*x+a2*x2+......ak*xk称为序列a0,a1,a2,.......ak,......的母函数(即生成函数)。

    例如:序列1,2,3.......n的生成函数为:G(x)=x+2x2+3x3+........nxn。点此链接:百度百科

    特别的当序列为:1,1,1,1,.......1,这个生成函数为:G(x)=x+x2+x3+.......+xn=(1-xn)/(1-x),当-1<x<1时G(x)=1/(1-x)

    1/(1-x)n=1+C(n,1)x+C(n+1,2)x2+C(n+2,3)x3+...+C(n+k-1,k)xk+...可以把生成函数还原为数列。

    ==========================================================================================================================

    例 1:使用母函数求出斐波那契数列的通项公式。Fib(n)=Fib(n-1)+Fib(n-2),这里假设Fib(1)=1,Fib(2)=1;

    求解这种递推关系的方法是:①、将递推关系变成母函数方程;②、求解母函数方程;③、将母函数变成幂级数形式。

    所以斐波那契数列的生成函数为:G(x)=x+x2+2x3+3x4+5x5+8x6..........。

    等式两边同时*x有:xG(x)=x2+x3+2x4+3x5+5x6+8x7+.......。

    相加有:G(x)+xG(x)=x+2x2+3x3+5x4+8x5+13x6+........。

    我们对比G(x)可以得到:G(x)+xG(x)=G(x)/x-1;所以我们可以得到:G(x)=x/(1-x-x2)。

    可以令:1-x-x2=0,得到两根为:a=(1-√5)/2,b=(1+√5)/2,所以我们可以知道:1-x-x2=(x-x1)(x-x2)=(1-ax)(1-bx);

    假设x/(1-x-x2)=m/(1-ax)+n/(1-bx),通分有:x=m(1-bx)+n(1-ax).由系数关系可得m=-1/√5,n=1/√5,所以G(x)=-1/√5(1-bx)+1/√5(1-ax)。

    我们可知:1/(1-bx)=1/[1-(1+√5)/2x]是以公比为(1+√5)/2的等比数列,1/(1-ax)是以公比为(1-√5)/2的等比数列,所以其通项公式为:Fib(n)=1/√5[bn+1-an+1]。

    ==========================================================================================================================

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

    构造母函数,如果用x的指数表示称出的重量,则:
    1个1克的砝码可以用函数1+x表示,(前面的这个1表示1克的砝码个数为0)
    1个2克的砝码可以用函数1+x2表示,
    1个3克的砝码可以用函数1+x3表示,
    1个4克的砝码可以用函数1+x4表示,

    那么几种砝码的组合情况的用乘积表示有:(1+x)(1+x2)(1+x3)(1+x4)=1+x+x2+2x3+2x4+2x5+2x6+2x7+x8+x9+x10 ,系数即为方案数

    例称出重量为6的物品:①、1,2,3;②、2,4两种方案。

    ==========================================================================================================================

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

    这个相对于上面的那个例子是:这个邮票可以重复。可知其生成函数为:G(x)=(1+x+x2+....)(1+x2+x4+....)(1+x3+x6+...),同理展开后其系数即为方案数。

    ==========================================================================================================================

    例题4:德.梅其里亚克称重问题

    (1)重为a1,a2,a3.....ak的砝码,如何放在天平的两端,记可称重量为n的物体的不同方式为Cn,则Cn的母函数为:

    G(x)=(x-a1+1+xa1)(x-a2+1+xa2).........(x-ak+1+xak) ------ x-a1表示砝码a1和物体放在同一个托盘内,xa1表示砝码和物体放在不同的托盘内,1则为不用这个砝码。

    (2)重为a1,a2,a3....ak的砝码,如只可以放在天平的一端,记可称重量为n的物体的不同方式为Cn,则Cn的母函数为:

    G(x)=(1+xa1)(1+xa2).........(1+xak)

    ==========================================================================================================================

    例题5:数的划分,将整数分解为若干个整数(相当于将n个苹果放在n个无区别的盘子里,每个盘子可以放多个,也可以不放),上一篇博文中有提到。

    假设1出现的次数为记为a1,2出现的次数记为a2.........k出现的次数记为ak,那么生成函数为:

    G(x)=(1+x+x2+x3+x4+.....)(1+x2+x4+x6+x8+......)(1+x3+x6+x9+....)........(1+xn)

    前面的1+x2+x4+x6+x8+......意思是当出现一个2时为x2,当出现两个2时为x4.....,为什么当出现n时,只有两项(1+xn),因为是将数n划分为若干项,所以不能超过该数,且由数1到n项数依次要<=n/k(k=1.2,3,4...n)。

    还是以nyist 90(数的划分)为例:这里就直接套用网上的模板了

    1. #include<iostream>  
    2. #include<cstring>  
    3. #include<algorithm>  
    4. using namespace std;  
    5. const int MAX=50;  
    6. #define CLR(arr,val) memset(arr,val,sizeof(arr))  
    7. int n,m,value[MAX],temp[MAX];  
    8. int main()  
    9. {   cin>>m;  
    10.     while(m--)  
    11.     {   cin>>n;  
    12.         fill(value,value+MAX,1);//value用来存储系数   
    13.         CLR(temp,0);//temp用来保存每一次的情况  
    14.         for(int i=2;i<=n;i++)                                                          
    15.         {   for(int j=0;j<=n;j++)  
    16.                 for(int k=0;k+j<=n;k+=i) //控制每次系数的变化和每个数出现的最大项数   
    17.                     temp[k+j]+=value[j];    
    18.             for(int j=0;j<=n;j++)  
    19.                 value[j]=temp[j],temp[j]=0;  
    20.         }  
    21.         cout<<value[n]<<endl;   
    22.     }  
    23.     return 0;  
    24. }  

    ==========================================================================================================================

    例题2:hdu 1085(硬币问题)

    1. //有3种面额是1、2、5的硬币,输入3个数字代表每种硬币的枚数,求最小的不能由这些硬币组成的面额是多少?  
    2. #include<iostream>  
    3. #include<cstring>  
    4. #include<algorithm>  
    5. using namespace std;  
    6. const int MAX=8010;  
    7. #define CLR(arr,val) memset(arr,val,sizeof(arr))  
    8. int value[MAX],temp[MAX],num[3],coin[3]={1,2,5};  
    9. int main()  
    10. {   while(cin>>num[0]>>num[1]>>num[2])  
    11.     {   if(num[0]+num[1]+num[2]==0) break;  
    12.         int max=num[0]+2*num[1]+5*num[2];  
    13.         CLR(value,0);  
    14.         CLR(temp,0);  
    15.         fill(value,value+num[0]+1,1);  
    16.         for(int i=1;i<3;i++)  
    17.         {   for(int j=0;j<=max;j++)  
    18.                 for(int k=0;k+j<=max&&k/coin[i]<=num[i];k+=coin[i])//注意不能超出个数  
    19.                     temp[k+j]+=value[j];  
    20.             for(j=0;j<=max;j++)  
    21.                 value[j]=temp[j],temp[j]=0;  
    22.         }  
    23.         for(i=0;i<=max+1;i++)//遍历即可  
    24.             if(value[i]==0) {cout<<i<<endl;break;}  
    25.     }  
    26.     return 0;  
    27. }  

    涉及到母函数的题目有:HDU 1171,1398,1709,2065,2069,2082,2152;POJ 3046,3716,3734等等~有空再做下,还有很多东西不懂,应该先归纳下其它的知识~~

  • 相关阅读:
    四校联考【20171001】
    C语言基础知识
    页表和TLB
    python
    Cache组织方式
    On the Spectre and Meltdown Processor Security Vulnerabilities
    latex-组织文本
    深入理解计算机系统
    深入理解计算机系统-计算机系统漫游
    逻辑地址到物理地址的转换
  • 原文地址:https://www.cnblogs.com/13224ACMer/p/4671551.html
Copyright © 2020-2023  润新知