ACM训练日记—12月24日

本文介绍了母函数的基本概念及其在组合数学问题中的应用,并通过两个典型例题详细展示了如何使用母函数来解决硬币组合问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        这个周真是够呛,接连的考试考得我一阵心里凉凉QAQ。复变还没怎么看就考了,估计就算过了也的不了多少分。不过这波考试过去总算有相当长的时间去复习常微分(必须在这科打翻身仗)。而且接下来有充足的时间去联系学习acm。下面总结一下最近学的新知识,和做的一些题目吧,零零散散的,总结重要的。

       母函数:(这是漏掉整理的一部分,非常好用,可以解决一类问题)

       定义:对于任意数列a0,a1,a2…an 即用如下方法与一个函数联系起来:G(x) = a0 + a1x + a2x*2 + a3x^3...+ anx^n则称G(x)是数列的生成函数。

       其实我的理解就是一种将组合数学的问题通过映射,将实际问题建立一一映射,映射到幂级数上,利用幂级数的加(与)与乘(或)的关系解决问题。

      举个例子:有3个1元,1个2元,1个5元,问能够组成多少种价值的钱。   不难看出可以有 1,2,3,4,5,,,,10。那么我们设a*x^n,代表n元硬币又a个,那么设(1+x+x^2+x^3)(1+x^2)(1+x^5),如果把它展开,不难发现b*x^i代表 i 元硬币有b个的答案,因为上式(1+x+x^2+x^3)代表1元选0个或选1个或选2个或选3个,而选1元和选2元是互不影响的,所以用乘起来,表示一种或的关系,所以就是一种一一映射了。

      我讲的不大好,推荐几位大佬的博客http://blog.youkuaiyun.com/xiaofei_it/article/details/17042651  和 http://blog.youkuaiyun.com/metalseed/article/details/8046656

      又在杭电上水了几题。

      hdu 1028   Ignatius and the Princess III

      题意:给出一个数n,找出用1,2,,,n选出若干不同种的数加和成n,求多少种组法。比如:

4 = 4;
4 = 3 + 1;
4 = 2 + 2;
4 = 2 + 1 + 1;
4 = 1 + 1 + 1 + 1;

      这个题的母函数就很简单(1+x+x^2+...x^n)(1+x^2+x^4+...)....(1+x^n)展开这个多项式就行了,至于展开多项式具体方法,看代码注释吧。

int c1[1000], c2[1000];
int val[1000];
int main()
{
    int n;
    while(cin>>n)
    {
        for(int i=1;i<=n;i++)//存有多少种指数
        {
            val[i]=i;
        }
        memset(c1,0,sizeof(c1));
        memset(c2,0,sizeof(c2));
        for(int i=0;i<=n;i++)//相当于(1+x+x^2+...x^n),利用c1作标记指数 i 的x^i前的系数
        {
            c1[i]=1;
        }
        for(int i=2;i<=n;i++)//所有指数依次合并
        {
            for(int j=0;j<=n;j++)//两个多项式合并
            {
                for(int k=0;k+j<=n;k+=val[i])
                {
                    c2[j+k]+=c1[j];
                }
            }
            for(int j=0;j<=n;j++)//传导给c1,在继续合并。
            {
                c1[j]=c2[j];
                c2[j]=0;
            }
        }
        cout<<c1[n]<<endl;
    }
    return 0;
}

       hdu 1398     Square Coins

题意:有17中硬币,面额分别为1 , 2^2 , 3^2 , 4^2 ,,,,17^2。给出一个数n,求有多少种组法,相当于和上面的题一样。很简单。

int c1[100005],c2[100005];
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        if(n==0) break;
        memset(c1,0,sizeof(c1));
        memset(c2,0,sizeof(c2));
        for(int i=0;i<=n;i++)
        {
            c1[i]=1;
        }
        for(int i=2;i*i<=n;i++)//所有i*i小于n的幂级数多项式
        {
            for(int j=0;j<=n;j+=(i*i))//注意这里加的是i*i。
            {
                for(int k=0;k+j<=n;k++)
                {
                    c2[j+k]+=c1[k];
                }
            }
            for(int j=0;j<=n;j++)
            {
                c1[j]=c2[j];
                c2[j]=0;
            }
        }
        cout<<c1[n]<<endl;
    }
    return 0;
}

       母函数的题目还算好做,主要是这一类的题。下整理这两道有代表性的吧,刚做的其他母函数题更水。

另外,还打了一次牛客网比赛,我还是一如既往的菜,至少让我长记性0也是完全平方数。另外在vj上找到了其他数学专题,是其他学校的吧,接下来两周,概率期望,全面开始。

对了还有莫比乌斯反演下一篇整理一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值