母函数(生成函数)

来源:互联网 发布:四川理工学院网络教学 编辑:程序博客网 时间:2024/06/06 00:45

http://www.wutianqi.com/?p=596


ACM中常用的母函数大致分为两类,第一类是普通型,第二种是指数型。两种都在上述大牛的博客中有讨论。对于第二种指数型可参考hdu2065

#include <iostream>using namespace std;// Author: Tanky Woo// www.wutianqi.comconst 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){memset(c2,0,sizeof(c2)); for(i=0; i<=nNum; ++i)   // ---- ①{c1[i] = 1;}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;}


主要对模板进行解释。

该模板公式可表示为: (1 + x^1 + x^2 + x^3 ....)*(1+ x^2 + x^4 +....)*(1+ x^3 + x^6 +....)

我们的任务就是模仿上式的展开。

①  首先c2数组必须清空为0,它的作用后边再讲。 这里是根据第一个表达式进行赋值,因为第一个表达式的步长为1,所以i每次加1,赋值成1是因为假如只有这一个表达式,那么它组成每种给定质量的情况都是1。

② 这里的i实际上表示的是步长,同时也指的是第二个表达式。比如说第一个表达式步长为1,第二个步长为2,第三个步长为3,所以i每次加1. 遍历到nNum是因为,当步长大于nNum时,x的指数一定大于nNum。

③ 我们把一个多个表达式相乘的问题,分解成了两个两个相乘的问题,即第一次是第一个表达式和第二个表达式相乘,它们的结果是一个新的表达式,我们暂且叫它temp,那么下一次我们要做的就是拿temp和第三个表达式相乘。  而这里的j指的就是前一个表达式各个项的指数,比如对于第二个表达式来说,第一项的指数是0,第二项的指数是2,第三项的指数是4。

④  k是指后一个表达式中各个项的系数。  所以j+k就是对应两项相乘后等到的项的系数。c2默认值是0,表示对于每个给定的质量,现在可以组成的情况都是0种,然后不断的加c1[j] 这里有点难理解,我也说不清楚。

⑤ 将中间变量的值赋给最后的保存结果的数组。 然后更新c2以进行下一次的记录。


上述模板只是对于每种质量的砝码个数无限的情况下,对于有限砝码的情况请见大神博客里面的题(尤其是3,4题)


0 0
原创粉丝点击