母函數(shù)(Generating function)詳解 — TankyWoo

(一)普通母函數(shù):##

http://www.wutianqi.com/?p=596

#include <iostream>
using namespace std;
// Author: Tanky Woo
// www.wutianqi.com
const int _max = 10001; 
// c1是保存各項質(zhì)量砝碼可以組合的數(shù)目
// c2是中間量,保存沒一次的情況
int c1[_max], c2[_max];   
int main()
{   //int n,i,j,k;
    int nNum;   // 
    int i, j, k;
 
    while(cin >> nNum)
    {
        for(i=0; i<=nNum; ++i)   // ---- ①
        {
            c1[i] = 1;
            c2[i] = 0;
        }
        for(i=2; i<=nNum; ++i)   // ----- ②
        {
 
            for(j=0; j<=nNum; ++j)   // ----- ③
                for(k=0; k+j<=nNum; k+=i)  // ---- ④
                {
                    c2[j+k] += c1[j];
                }
            for(j=0; j<=nNum; ++j)     // ---- ⑤
            {
                c1[j] = c2[j];
                c2[j] = 0;
            }
        }
        cout << c1[nNum] << endl;
    }
    return 0;
}

① 、首先對c1初始化,由第一個表達(dá)式(1+x+x2+..xn)初始化,把質(zhì)量從0到n的所有系數(shù)都初始化為1.
② 、 i從2到n遍歷,這里i就是指第i個表達(dá)式,上面給出的第二種母函數(shù)關(guān)系式里,每一個括號括起來的就是一個表達(dá)式。
③、j 從0到n遍歷,這里j就是(前面i個表達(dá)式累乘的表達(dá)式)里第j個變量,(這里感謝一下seagg朋友給我指出的錯誤,大家可以看下留言處的討論)。如(1+x)(1+x2)(1+x3),j先指示的是1和x的系數(shù),i=2執(zhí)行完之后變?yōu)椋?+x+x2+x3)(1+x^3),這時候j應(yīng)該指示的是合并后的第一個括號的四個變量的系數(shù)。
④ 第j個指數(shù)的冪可以增加的數(shù)為k,k每次增i。( 因為第i個表達(dá)式的增量是i:(1+xi+x2i+...+x^ni+...) )。
⑤ 、把c2的值賦給c1,而把c2初始化為0,因為c2每次是從一個表達(dá)式中開始的。

https://vjudge.net/problem/HDU-1028

#include <cstdio>
using namespace std;
const int maxn= 125;
// c1是保存各項質(zhì)量砝碼可以組合的數(shù)目
// c2是中間量,保存每一次的情況
int c1[maxn], c2[maxn];
int main()
{   int n;
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=0;i<=n;i++)
        {
            c1[i]=1;
            c2[i]=0;
        }
        for(int i=2;i<=n;i++)
        {
            for(int j=0;j<=n;j++)
            {
                for(int k=0;k+j<=n;k+=i)
                {
                    c2[j+k]+=c1[j];
                }
            }
            for(int j=0;j<=n;j++)
            {
                c1[j]=c2[j];
                c2[j]=0;
            }
        }
        printf("%d\n",c1[n]);
    }
    return 0;
}

(二)指數(shù)母函數(shù)##

指數(shù)型母函數(shù)主要是關(guān)于排列組合方面的問題。
分別看兩個比較典型的問題對比:
普通母函數(shù)問題:有紅球兩個,白球、黃球各一個,試求有多少種不同的組合方案。
指數(shù)型母函數(shù)問題:假設(shè)有8個元素,其中a1重復(fù)3次,a2重復(fù)2次,a3重復(fù)3次。從中取r個元素,求其排列數(shù)。
下面是指數(shù)型母函數(shù)的定義


zhishumuhanshu3

對于上面的問題“假設(shè)有8個元素,其中a1重復(fù)3次,a2重復(fù)2次,a3重復(fù)3次。從中取r個組合,求其組合數(shù)?!保?br> (感謝 3Dnn 同學(xué)指出,下圖的 28/3! 應(yīng)該改為 26/3!)
zhishumuhanshu4

https://vjudge.net/problem/HDU-1521
題意:有n種物品,并且知道每種物品的數(shù)量。要求從中選出m件物品的排列數(shù)。例如有兩種物品A,B,并且數(shù)量都是1,從中選2件物品,則排列有"AB","BA"兩種。

#include <cstdio>
#include<string.h>
using namespace std;
const int maxn=11;
double c1[maxn],c2[maxn];
int factor[maxn];
int num[maxn];
int main()
{
    factor[0]=1;
    for(int i=1;i<=10;i++)
        factor[i]=factor[i-1]*i;
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(int i=1;i<=n;i++)
            scanf("%d",num+i);
        memset(c1,0,sizeof(c1));
        memset(c2,0,sizeof(c2));
        for(int i=0;i<=num[1];i++)
        {
            c1[i]=1.0/factor[i];
        }
        for(int i=2;i<=n;i++)
        {
            for(int j=0;j<=m;j++)
            {
                for(int k=0;j+k<=m&&k<=num[i];k++)
                {
                    c2[j+k]+=c1[j]/factor[k];
                }
            }
            for(int j=0;j<=m;j++)
            {
                c1[j]=c2[j];
                c2[j]=0;
            }
        }
        printf("%.f\n",c1[m]*factor[m]);
    }
    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容