ACM 母函数专题

作者: ccccsober | 来源:发表于2016-06-29 09:30 被阅读1142次

    普通母函数

    这个很模板...但我发现 貌似这个和背包是一样的,各种各样的背包似乎都可以用母函数做,但这个我没研究过高阶的背包问题,如果不对希望大神们指出。
    数学理论上面的问题在wiki和各位大神的博客都有,帮大家列出网址:
    wiki百科
    良心大作,连题目链接都给出来了
    这里给出一个参考模版:

        int c1[MAX];
        int c2[MAX]; 
        _init();
        int Max=0;
        for(int i=0;i<n;i++){
            scanf("%d%d",&value[i],&num[i]);
            Max+=value[i]*num[i];
        }
        for(int i=0;i<=num[0];i++)
            c1[i*value[0]]=1;
        for(int i=1;i<n;i++){
            for(int j=0;j<=(Max>>1);j++){
                for(int k=0;k<=num[i]&&(j+k*value[i])<=(Max>>1);k++)
                    c2[j+k*value[i]]+=c1[j];
            }
            for(int i=0;i<=(Max>>1);i++){
                c1[i]=c2[i];
                c2[i]=0;
            }
        }
    
    

    指数型母函数

    参考文献:
    (母函数的理论推导)[http://www.cnblogs.com/silencExplode/archive/2011/03/05/1971397.html]
    指数型母函数:对于序列函数称为序列的指数型母函数。这样对于一个多重集,其中a1重复了n1次,a2重复了n2次,a3重复了n3次,如果从n个元素中取r个元素排列,不同的排列数所对应的指数型母函数为:

    Screen Shot 2016-06-29 at 9.04.25 AM.png
    一开始我一只不理解为什么它和普通的母函数不同,一定要加一个n!,现在想想 不尽异集的全排列的推导,一下就得到结果了。
    它主要有几个常见的应用情况,可以参
    考下面的公式
    Screen Shot 2016-06-29 at 9.07.48 AM.png
    给出几个真正的习题让大家参考一下:
    (HDU的红色病毒)[http://acm.hdu.edu.cn/showproblem.php?pid=2065]
    这个题就是 两个“偶数”+两个“奇数”,配合泰勒展开即可

    值得一提的是这个题可以有 状态压缩 的递推做法,我觉得很好,下次写下来
    下面给出AC代码
    //
    //  main.cpp
    //  hdu 2065 "红色病毒"问题
    //
    //  Created by ccccsober on 6/29/16.
    //  Copyright © 2016 cccsober. All rights reserved.
    //
    #include <iostream>
    #include <algorithm>
    #include <cassert>
    #include <string>
    #include <sstream>
    #include <math.h>
    #include <set>
    #include <bitset>
    #include <vector>
    #include <stack>
    #include <map>
    #include <queue>
    #include <deque>
    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <ctime>
    #include <cctype>
    #include <complex>
    using namespace std;
    //const int MAX1=   ;
    //const int MAX2=    ;
    const int Mod=   100  ;
    const double plus=0.49999999;
    const int INF=0x3f3f3f3f;
    typedef long long LL;
    typedef unsigned long long ULL;
    //#define M_PI 3.141592653589
    int quick_pow(int a,LL n){
        if(!n) return 1;
        int ans=quick_pow(a,n>>1)%Mod;
        ans=(ans*ans)%Mod;
        if(n&1) ans*=a;
        return ans%Mod;
    }
    int main(int argc, const char * argv[]) {
        freopen("/Users/sperc4/Desktop/input.txt", "r", stdin);
        int t;
        while(scanf("%d",&t)!=EOF&&t){
            for(int i=1;i<=t;i++){
                LL n;       //讲道理,应该是要ULL,但LL过了就凑合吧...
                scanf("%lld",&n);
                int ans=quick_pow(4,n-1)+quick_pow(2,n-1);
                ans%=100;
                printf("Case %d: %d\n",i,ans);
            }
            cout<<endl;
        }
        fclose(stdin);
        //      fclose(stdout);
        return 0;
    }
    
    

    总的来说,母函数还是比较简单的:
    1.对于普通母函数:理解c1[],c2[]的作用, 不定方程的非负整数解的 隔板法皆可。
    2.对于指数母函数:理解 泰勒展开&&不尽异集全排列组合公式。

    相关文章

      网友评论

        本文标题:ACM 母函数专题

        本文链接:https://www.haomeiwen.com/subject/httxjttx.html