母函数简介及简单使用(附HDU 1284 钱币兑换问题 解题报告)

       通常来说,母函数的思想就是使用幂级数来表示一个离散数列。例如对于一个数列是a={a0,a1,a2,-------ak},那么我们可以母函数的定义就是G(x)=a0+a1*x+a2*x^2+a3*x^3------an*x^n,这里的G(x)就是数列a的母函数。

       母函数可以用来解决整数拆分问题,下面举一个例子来说明。

       例如我们有重量为1克、2克、3克、4克的砝码各一个,那么问你这些砝码可以称出几中重量?每一种重量有多少种方案数?

       对于这个问题我们可以这样定义母函数G(x)=(1+x)*(1+x^2)*(1+x^3)*(1+x^4),那么这个时候我们把G(x)展开之后得到一个多项式,这个时候的指数就是可以称出的重量,对应的该指数的系数就是该重量对应的称出的方案数,自己展开看看就知道了。

      下面我们说说HDU 1284 的“钱币兑换问题”吧,题目的意思就是说给你三种面值的币分别是1分、2分、3分,那么问你一个钱数n有几种方案可以拼凑得到这个钱数n?

      这道题还是比较好看的,我们根据母函数的定义,以及多项式的每一项和系数所表示的含义,我们可以定义母函数G(x)=(1+x+x^2+x^3--------)*(1+x^2+x^4+x^6+x^8--------)*(1+x^3+x^6+x^9--------------),那么我们使用母函数的额展开式对应的指数就是能表示的钱币数,系数就是表示该钱币数的方案数。

       所以问题就是求出对应的n的系数就可以了,这个比较简单,就是模拟手工多项式的展开,下面附上我的AC代码供参考:

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
using namespace std;
const int Max=32769;
int ans[Max];
int tans[Max];

int main()
{
    int i,j,n;
    for(int i=0;i<Max;i++)
        ans[i]=1;
    memset(tans,0,sizeof(tans));
    for(int k=2;k<=3;k++)
    {
        for(i=0;i<Max;i++)
        {
            for(j=0;i+j<Max;j+=k)
            {
                tans[i+j]+=ans[i];
            }
        }
        for(i=0;i<Max;i++)
        {
            ans[i]=tans[i];
            tans[i]=0;
        }
    }
    while(scanf("%d",&n)!=EOF)
    {
        printf("%d\n",ans[n]);
    }
    return 0;
}

你可能感兴趣的:(母函数简介及简单使用(附HDU 1284 钱币兑换问题 解题报告))