ACM 母函数专题

普通母函数

这个很模板...但我发现 貌似这个和背包是一样的,各种各样的背包似乎都可以用母函数做,但这个我没研究过高阶的背包问题,如果不对希望大神们指出。
数学理论上面的问题在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.对于指数母函数:理解 泰勒展开&&不尽异集全排列组合公式。

推荐阅读更多精彩内容

  • 在编程中我们总要进行一些数学运算以及数字处理,尤其是浮点数的运算和处理,这篇文章主要介绍C语言下的数学库。而其他语...
    欧阳大哥2013阅读 3,946评论 0 12
  • (一)普通母函数:## http://www.wutianqi.com/?p=596 ① 、首先对c1初始化,由第...
    Gitfan阅读 1,153评论 0 1
  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 2,593评论 0 4
  • 今天冬至要吃饺子 我突然发现长辈都喜欢说原汤化原食 这让我突然想到了学习语言的时候有个理论 就是很多时候你其实不...
    5a14902a06d7阅读 149评论 0 0
  • 在茫茫人海中,驻足在车水马龙的街头,看沧海桑田,听嘈杂的卖叫声,感受着人世间最淳朴的生命活力,我知道了我的方向。
    悦玺阅读 618评论 0 0
  • 黑色的光困住的热安静的房间里洗衣机在转动 那搅动的波浪是夜里另类的声色犬马和梦里动听的欲盖弥彰
    1601阅读 205评论 0 0