HDOj 母函数详解

知识点:组合数学之母函数
研究一下形式
HDOj 母函数详解_第1张图片

可以看出:

x^2项的系数a1a2+a1a3+...+an-1an中所有的项包括n个元素a1,a2, …an

中取两个组合的全体;同理x^3项系数包含了从n个元素a1,a2, …an中取3

个元素组合的全体。以此类推。


母函数是用于对应一个无穷序列的幂级数,一般来说母函数有形式:


我们称G(x)是序列 g0,g1,g2…………的母函数

for example:
若有1克、2克、3克、4克的砝码各一 枚,能称出哪几种重量?各有几种可能方案?
如何解决这个问题呢?考虑构造母函数。

如果用x的指数表示称出的重量,则:

1个1克的砝码可以用函数1+x表示,
1个2克的砝码可以用函数1+x2表示,
1个3克的砝码可以用函数1+x3表示,
1个4克的砝码可以用函数1+x4表示,

几种砝码的组合可以称重的情况,可以用以上几个函数的乘积表示:
(1+x)(1+x^2)(1+x^3)(1+x^4)
=(1+x+x^2+x^3)(1+x^3+x^4+x^7)
=1+x+x^2+2x^3+2x^4+2x^5+2x^6+2x^7+x^8+x^9+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  
同理,对于整数拆分也用类似方法,例如对5进行拆分

整数1 用 函数 1+x+x^2+x^3+x^4+x^5 (ps 因为所有的1都”一样“,所以两个1时即x^2时系数为1)表示
整数2 用 函数 1+x^2+x^4 表示
整数3 用 函数 1+x^3 表示
整数4 用 函数 1+x^4表示
整数5 用 函数 1+x^5表示


所有的式子相乘,得到x^5的系数即为拆分数
因此程序处理点在于多项式相乘,可用矩阵法,注意优化

程序代码:  AC
#include<stdio.h>
#define N 130
int a[N+1],b[N+1];
int main()
{
 int i,j,n,k;
 while(scanf("%d",&n)!=EOF && n)
 {
  for(i=0;i<=n;i++)
  {a[i]=1;b[i]=0;}
  for(i=2;i<=n;i++)
  {
   for(j=0;j<=n;j++)
    for(k=0;k+j<=n;k+=i)
     b[k+j]+=a[j];
   for(j=0;j<=n;j++)
   {
    a[j]=b[j];b[j]=0;
   }
  }
  printf("%d\n",a[n]); 
 }
 return 0;
}


你可能感兴趣的:(优化)