母函数入门小结

    技术2025-02-01  18

    要想了解母函数的详细知识点,建议学习HDU刘春英老师PPT《母函数及其应用》。

    在这里可以找到这个PPT:http://acm.hdu.edu.cn/forum/show.php

           母函数适合求解这类题目,如已知有1克砝码2个,2克砝码3个,3克砝码四个,求这些砝码所能组成的所有重量以及每种重量都有几种组合方式。对于序列a0,a1,a2,...构造一函数G(x)=a0+a1x+a2x^2+...,则称G(x)为a0,a1,a2...的母函数。 一个1克砝码可以表示为1+x; 一个2克砝码可以表示为1+x^2 ...        两个1克砝码表示为1+2x?,不对,两个1克砝码可以表示1克,也可以表示2克,所以表示为1+x+x^2同理,三个2克砝码就可以表示为1+x^2+x^4+x^6那么这些砝码总共能表示多少种组合呢,把他们相乘就可以了。        如一克两克三克砝码各一个,表示为(1+x)(1+x^2)(1+x^3)=1+x+x^2+2x^3+x^4+x^5+x^6,即一克一种(1),两克一种(2),三克两种(1+2,3),四颗一种(1+3),五克一种(2+3),六克一种(1+2+3)则有1克砝码2个,2克砝码3个,3克砝码四个的所有组合数就应该会求了,就是(1+x+x^2)(1+x^2+x^4+x^6)(1+x^3+x^6+x^9+x^12)=...... 只要自己认真在纸上画几遍就明白了! 下面是解决母函数题目最通用的模版,做了20多道总结的! //nump代表因子,numx代表因子个数,(注意:因子不一定从1开始) //sumnum[i]表示组合结果为 i的数目 设置curnum[]数组来保存中间结果 scanf("%d%d",&nump,&numx); memset(curnum,0,sizeof(curnum)); memset(sumnum,0,sizeof(sumnum));//对两个数组要进行初始化操作 for(int i=1;i<=numx;i++) scanf("%d%d",&arrp[i],&arrk[i]); for(int i=0;i<=arrp[1]*arrk[1];i+=arrp[1]) sumnum[i]=1;//先对第一个式子初始化 for(int i=2;i<=numx;i++)//依次将编号2—numx的式子相乘(每次两个式子相乘结果保存在sumnum[]中) { for(int j=0;j<=nump;j++)//表示被乘数的x^j的系数。也即j指前i个表达式乘完之后的x^j的系数 { for(int k=0;k+j<=nump&&k<=arrp[i]*arrk[i];k+=arrp[i])//k表示当前第i个式子的指数 { curnum[k+j]+=sumnum[j];//k+j表示被乘数x^j的系数与乘数x^k的系数之和。即(x^j*x^k)的系数 } } for(int j=0;j<=nump;j++)//每乘完一个式子,将结果保存在sumnum[]中 { sumnum[j]=curnum[j]; curnum[j]=0;//将中间组数清零继续进行下一轮乘法运算 } } printf("%d/n",sumnum[nump]);//输出组合结果为nump的组合数
    最新回复(0)