HDU1028整数拆分(母函数)

这道题是一道母函数的题,看过很多大牛讲母函数,看的一脸懵逼,大脑接受不了大牛的教导,今天突然感觉开窍了,想起了高中老师教的组合数学,终于有点眉目了,希望本篇博文能对组合数学不好的同学有所帮助(组合数学好的估计会觉得本博客毫无营养);
首先,我要说明,这里讲的是指数型母函数(其实就是利用指数的母函数),以整数拆分为例讲解一下
我们用x的指数代表数值大小,系数代表有几种取法(或者说拆分方法),举个例子:
记住系数代表取法,看完了最好自己试试,以4为例就好
a*x^b 代表整数b有a种拆分方法
那样我们用n个代数式代表拆分成1,2,3,…..n的个数(1代表x^0)
如(1 + x +x^2 + x^3……)
不划分一(即不用1来拆分) , 1个 , 2个 , 3个……
(1+ x^2 +x^4 + x^6……………)
0个2 ,1个2 ,2个2,(所以x系数是4), ,三个2.系数为6……
以此类推;
以4为例讲解一下如何拆分
x^4=x*x*x*x(即取四个一)
x^4=x*x*x^2(两个一,一个二)
x^4=x^2+x^2(两个二)
x^4=x*x^3(一个一,一个三)
x^4=x^4(一个四)

接下来讲解一下乘法原理
(a*b*c*d)*(d*e*f*g)
的结果就是依次从第一个代数式选择一个与第二个代数式中选择一个相乘的乘积

整数拆分的核心
(1+x+x^2+x^3+x^4….)(1+x^2+x^4…..)(1+x^3….)*(1+x^4…)…

接下来就是完整的做了。还是以4为例
因为整数4不能由5个1,6个1,7个1等等组成
也不能由3个2,4个2 ,5个2….组成
同理也不能有多个5,6 , 7组成,
所以4的组成代数式为
(1+x+x^2+x^3+x^4)(1+x^2+x^4)(1+x^3)*(1+x^4)=
1+x+2*x^2+3^x^3+5*x^4
所以整数4有5种拆分方式

x^4=x^4*1*1*1(即取四个一)(1取4次,2不取,3不取,4不取)
x^4=x^2*x^2*1*1(两个一,一个二)
x^4=1*(x^4)*1*1(两个二)
x^4=x*1*x^3*1(一个一,一个三)
x^4=1*1*1*x^4(一个四)

于是整数拆分就变成了代数式计算
(1+x+x^2+x^3+x^4….)(1+x^2+x^4…..)(1+x^3….)*(1+x^4…)…
code:

#include
#include
#include
#include
#include
#include
#include 
using namespace std;
#define ll long long
#define mem(a) memset(a,0,sizeof(a))
const int eps=1e-8;
const int maxn=130;//须填写
const int inf=0x3f3f3f3f;
int a[maxn];//用来存储计算结果
int b[maxn];//存储中间量
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=0;i<=n;i++)
            a[i]=1;
        //把第一个代数式存进a[]
        for(int i=0;i1;i++)//结果依次与下一个代数式相乘
        //共n个代数式,需要乘n-1次
        {
            mem(b);
            for(int j=0;j<=n;j+=(i+2))
                for(int k=0;k+j<=n;k++)
                {
                    b[k+j]+=a[k];
                    printf("b[%d+%d]=%d",k,j,b[k+j]);
                }
                for(int i=0;i<=n;i++)
                     printf("%d\n",a[i]);
            memcpy(a,b,sizeof(b));//本次结果存进a[]
        }
        printf("%d\n",a[n]);
    }
    return 0;
}

仅仅是自己会了,写的有些乱,希望不要介意:)

你可能感兴趣的:(HDU,母函数,组合数学,整数拆分,HDU)