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<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<iostream>
#include<string>
#include <set>
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;i<n-1;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;
}

仅仅是自己会了,写的有些乱,希望不要介意:)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值