#对于母函数讲解

对于母函数,我第一次见还是在HDU2082上见到的,感觉是个很nb的思想,因为运用到了离散数学的知识,所以我在这里简单的介绍一下吧。

从一个比较经典的例子入手:
题目:有1克、2克、3克、4克的砝码各一 枚,能称出哪几种重量?每种重量各有几种可能方案?

因为每个砝码只有一种一枚,所以一般而言一共24种(即对于每个砝码而言称与不称),倘若是n个砝码,则是2n种。当然啦这太容易理解了。

但问题不会这么简单,所以!对于普通母函数——把组合问题的加法法则和幂级数的的乘幂的相加对应起来,这句话可能一开始难以理解,不过其实学完了之后很容易理解,母函数的思想很简单—就是把离散数列和幂级数一一对应起来,把离散数列间的相互结合关系对应成为幂级数间的运算关系,最后由幂级数形式来确定离散数列的构造。

我们需要用到幂级数运算的知识了:
假设1g的砝码,放的话是x1,不放的话是x0;2g的话,放的是x2,不放是x0;4g放的话是x4,不放是x0依次类推,注意这里应该是幂次方的关系,为了后面能加。所以我们再把题目化简:只有1g和2g两个砝码,能有几个放法?

解答:(x0+x1)(x0+x2)=x0+x1+x2+x3;

那么如果是一开始的题目嘞?
解答:(x0+x1)* (x0+x2) * (x0+x3)* (x0+x4)

=x0 + x1 + x2 + 2x3 + 2x4 + 2x5 + 2x6 + 2x7 + x8+ x9 + x10
注意,x前面是序数。

那么问题就迎刃而解了。一共有10种结果,16种组合法。

那么接下来,再加深一步,如果是每个硬币无穷个呢,硬币分别为1、2、3、4…直到无穷。
当然啦,还是运用到幂级数运算的想法了。当然一般会有个限定,那我限定硬币到5吧
那就是(x0+x1+x2+x3+x4+x5)(x0+x2+x4)(x0+x3)(x0+x4)(x0+x5)
很好理解吧!
展示一下代码:

#include
#include
#include
#include
#include
#include
#include
using namespace std;
int sup[1000],temp[1000];
int main()
{
 int target;
 int i,j,k;
 while(cin>>target){//输入希望得到的目标硬币和
  for(i=0;i<=target;i++){
   sup[i]=1;
   temp[i]=0;
  }
  for(i=2;i<=target;i++){
   for(j=0;j<=target;j++){
    for(k=0;k+j<=target;k+=i){
     temp[j+k]+=sup[j];
    }
   }
   for(j=0;j<=target;j++){
    sup[j]=temp[j];
    temp[j]=0;
   }
  }
  cout<<sup[target]<<endl;
 }
}

详情可以参考:https://blog.csdn.net/yu121380/article/details/79914529

你可能感兴趣的:(离散数学,acm算法)