• 母函数总结


    母函数总结

           观自      http://blog.csdn.net/metalseed/article/details/8046656#

    所谓母函数就是:将任意一个数列,a0,a1,a2……an 通过一个函数进行联系起来。

    G(n)=a0+a1*x+a2*x^2+……an*x^n; 称G(n)为数列的生成函数又叫母函数

           例如现在要从四个人中选出n个人来,那么她的母函数为G(x)= 1+4x+6x^2+4x^3+x^4,实际上就是二项式展开式,也就是(1+x)^4的展开式。关于展开式还有一个广义的公式 C(k,i)= k(k-1)(k-2)(k-i+1)/i!,这个公式不只作用于整数部分,在负数小数部分同样适用。

           母函数看的少点,还没有彻底理解,只能通过样例来讲解。如下:

    现在有面值1,2,3,4的金币各一个,让你求出所有能组成的金额,并且算出组成金额的方案数。

           现在假设x表示砝码,x的指数表示金币的金额,得到:(1+x)表示一个金币1,(1+x^2)表示一个金币2,(1+x^3)表示一个金币3,(1+x^4)表示一个金币4。

     

    这里这几个函数不好理解,这个1不是单纯的1,其实每个函数都是由a x^n表示的,

    指数n表示的是金币的金额,系数a表示金额n的金币拿多少,那么就拿(1+x)来说吧,他表示两个意思一个就是1*x^0也就是金额为零的金币拿一个,1*x^1就是金额为一的金币拿一个。实际上每个括号里函数表示的就是,相应金额的金币,拿与不拿。这样按照组合数学的思想就囊括了所有的情况。

     

    那么得到母函数G(n)= (1+x)* (1+x^2) *(1+x^3)* (1+x^4)。

     

    化简得到G(n)= 1+x+x^2+2x^3+2x^4+2x^5+2x^6+2x^7+x^8+x^9+x^10;

     

    这样得出金额为1-10组成方案数,分别为{1,1,2,2,2,2,2,,1,1,1}.

     

    这个方案按照组合代数的方法在纸上好实现,那么在代码中怎么实现呐?如下代码

    #include <iostream>
    using namespace std;
    const int _max = 10001;
    // c1是保存各项质量砝码可以组合的数目
    // c2是中间量,保存每一次的情况
    int c1[_max], c2[_max];
    int main(){
           int nNum; //你要查询组合数的金额
           int i, j, k;
           while(cin >> nNum){
                  for(i=0; i<=nNum; ++i){ // —- ① 首先对c1初始化,由第一个表达式(1+x+x2+..xn)初始化,把质量从0到n的所有砝码都初始化为1.
                         c1[i] = 1;
                         c2[i] = 0;
                  }
                  for(i=2; i<=nNum; ++i){ // —– ② i从2到n遍历,这里i就是指第i个表达式,上面给出的第二种母函数关系式里,每一个括号括起来的就是一个表达式。
                         for(j=0; j<=nNum; ++j) // —–   ③j从0到n遍历,这里j就是只一个表达式里第j个变量,比如在第二个表达式里:(1+x2+x4….)里,第j个就是x2*j.
                                for(k=0; k+j<=nNum; k+=i){ // —- ④//k表示的是第j个指数,所以k每次增i(因为第i个表达式的增量是i)。
                                       c2[j+k] += c1[j];
                                }
                         for(j=0; j<=nNum; ++j){ // —- ⑤把c2的值赋给c1,而把c2初始化为0,因为c2每次是从一个表达式中开始的
                                c1[j] = c2[j];
                                c2[j] = 0;
                         }
                  }
                  cout << c1[nNum] << endl;
           }
           /*
           ( 最外层,记录它正在与第几个多项式相乘。第二层,表示c1中的每一项,第三层表示后面被乘多项式中的每一项。)
           */
           return 0;
           
    }

     

  • 相关阅读:
    bzoj3675 [Apio2014]序列分割
    bzoj3206 [Apio2013]道路费用
    bzoj3205 [Apio2013]机器人
    bzoj4241 历史研究
    bzoj2821 作诗(Poetize)
    bzoj2724 [Violet 6]蒲公英
    bzoj2811 [Apio2012]Guard
    bzoj2809 [Apio2012]dispatching
    PHP 文字,图片水印,缩略图,裁切成小图(大小变小)
    PHP文件下载方式
  • 原文地址:https://www.cnblogs.com/wuwangchuxin0924/p/6362736.html
Copyright © 2020-2023  润新知