定义
对于序列a0,a1,a2,…构造一函数:
称函数G(x)是序列a0,a1,a2,…的母函数
实 例 分 析
例1:若有1克、2克、3克、4克的砝码各一 枚,能称出哪几种重量?各有几种可能方案?
如何解决这个问题呢?考虑构造母函数。
如果用x的指数表示称出的重量,则:
1个1克的砝码可以用函数1+x表示,
1个2克的砝码可以用函数1+x2表示,
1个3克的砝码可以用函数1+x3表示,
1个4克的砝码可以用函数1+x4表示,
几种砝码的组合可以称重的情况,可以用以上几个函数的乘积表示:
(1+x)(1+x2)(1+x3)(1+x^4)
=(1+x+x2+x3)(1+x3+x4+x^7)
=1+x+x2+2x3+2x4+2x5+2x6+2x7+x8+x9+x^10
从上面的函数知道:可称出从1克到10克,系数便是方案数。
例如右端有2x5 项,即称出5克的方案有2:5=3+2=4+1;同样,6=1+2+3=4+2;10=1+2+3+4。
故称出6克的方案有2,称出10克的方案有1
例2:求用1分、2分、3分的邮票贴出不同数值的方案数——
因邮票允许重复,故母函数为:
以展开后的x4为例,其系数为4,即4拆分成1、2、3之和的拆分数为4;
即 :4=1+1+1+1=1+1+2=1+3=2+2
推荐题目
HDU1028 Ignatius and the Princess III
思路:
母函数模板题:
整数拆分即把整数分解成若干整数的和(相当于把n个无区别的球放到n个无标志的盒子,盒子允许空,也允许放多于一个球)。
整数拆分成若干整数的和,办法不一,不同拆分法的总数叫做拆分数
Code:
#include <iostream>
#include<cstdio>
using namespace std;
#define M 120
int c1[M+1],c2[M+1];
void solve()
{
int i,j,k;
/*首先对c1初始化,由第一个表达式(1+x+x+..x)初始化,把质量从0到n的所有砝码都初始化为1.*/
for(i=0;i<=M;++i)
c1[i]=1;
/*i从2到n遍历,这里i就是指第i个表达式,上面给出的第二种母函数关系式里,每一个括号括起来的就是一个表达式。*/
for(i=2;i<=M;++i)
{
/*j 从0到n遍历,这里j就是(前面i个表达式累乘的表达式)里第j个变量。如(1+x)(1+x^2)(1+x^3),j先指示的是1和x的系数,i=2执行完之后变为
(1+x+x^2+x^3)(1+x^3),这时候j应该指示的是合并后的第一个括号的四个变量的系数。.*/
for(j=0;j<=M;++j)
{
/* k表示的是第j个指数,所以k每次增i(因为第i个表达式的增量是i)。*/
for(k=0;k+j<=M;k+=i)
{
c2[j+k]+=c1[j];
}
}
/*把c2的值赋给c1,而把c2初始化为0,因为c2每次是从一个表达式中开始的[2] */
for(j=0;j<=M;++j)
{
c1[j]=c2[j];
c2[j]=0;
}
}
}
int main()
{
solve();
int n;
while(scanf("%d",&n)!=EOF)
printf("%d\n",c1[n]);
return 0;
}
思路:
题意: 给你12,22,32,…172面值的这些硬币.然后问你一个数由这些数组成有多少种方法?
也是一道模板题,稍微变化一下即可,k的增量变成i*i即可
题目地址:
HDU1398 Square Coins
Code:
题意
给你1元,2元,5元硬币若干,问你由这些硬币不能组成的最小面值.
思路
需要稍微变化一下,因为这里限制了硬币的个数,并不是无限的.具体看代码
题目地址:
HDU1085 Holding Bin-Laden Captive!
Code:
题意:
给你一个天平和若干不同重量的砝码(确保砝码只有1个),让你输出从0到sum(sum=所有砝码加起来的值)所有不能称出来的重量.
思路:
有些重量也可以通过砝码间的相减得到.
需要变形:
该题使用的母函数有点特殊 因为x的次数可以为负
如测试数据
3
1 2 9
可以使用这样的母函数:(1+x+x-1)*(1+x2+x^-2) *(1+x9+x-9) ,
根据天枰的特点可以建模成像这样的母函数。
而算的时候是计算 (1+x+x2)*(1+x2+x^2) (1+x9+x18)/(1*x2x^9 ),
在该结果中大于0的指数中找 哪些指数的系数是0。
题目地址:
HDU1709 The Balance
Code:
题意&&思路:
求学分由给定的课程有多少种组成方式?(一样的学分课程没区别)标准的母函数模板式,直接套模板就行.
题目地址:
HDU 2079 选课时间
Code:
题意:
给你26个英文字母,A,B,C…X,Y,Z.价值依次是1,2,3,4…26.
现在让你求其能组成价值<=50的方法数,
例如 给出 A,B,C三个字母.那么能组成方法就是 A,B,C,AB,AC,BC,ABC7种
思路:
也是模板题,只要求出<=50的所有方式就行了
题目地址:
HDU 2082 找单词
Code:
题意:
给你1元,5元,10元,25元,50元的硬币若干枚,然后给你一个数问你能用这些硬币有多少种组成方案?
思路:
二话不说直接套模板,WA!What?好吧,仔细瞧瞧题,又有坑点!
Your program should be able to handle up to 100 coins.
硬币总数不能超过100枚!并且数字的0的组成方案也是1种