母函数定义以及习题练习

定义

对于序列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种

限制了硬币总数,咋办呢?当然有办法!
灵活变化!
开一个二维数组c1[][],,多一层循环用来控制硬币数量的变化.
详情见代码
题目地址:

HDU2069 Coin Change
Code:

传送门

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值