母函数简单实现

转自:Preeee

1.以一个问题为引例:重量为1,3,5g的砝码各两个,可以称出多少种重量不同的物品?

构造母函数G(x)=(1+x+x^2)(1+x^3+x^6)(1+x^5+x^10),其中x的指数表示砝码的重量,x表示砝码。

每个括号里代表的状态是取0个、取1个、取2个。

得到的各个x^n前面的系数就是每种质量可以称出的方案数目。所得式子的个数就代表可以称出多少种的重量。

2.再看另一种情况:重量为1,3,5g的砝码,可以称出某种质量的方案数目是多少?

构造母函数G1(X)=(1+x+x^2+x^3+......)(1+x^3+x^6+x^9+......)(1+x^5+x^10+x^15+......)

若质量为n,则x^n前面的系数就是方案数目。

以一个题为例:1、2、3、4.....元的面值可以组成面值为n的方案数有多少?

超级详细代码加思想:

#include <iostream>
using namespace std;
const int _max = 10001;
// c1是保存各项质量砝码可以组合的数目
// c2是中间量,保存没一次的情况
int c1[_max], c2[_max];
int main()
{
    int nNum;   //你想用已有的面值组成nNum大小的面值
    int i, j, k;
 
    //该代码的前提是假设所有面值为1、2、3、4、5元.....的连续数,即下面的 i
    //数量无限,即每种有无数张,每种可取0、1、2、3、4........
    while(cin >> nNum)
    {
        for(i=0; i<=nNum; ++i)   //此时的nNum是第一个括号的所有项个数  // ---- ①
        {
            c1[i] = 1;        //
            c2[i] = 0;
        }
        for(i=2; i<=nNum; ++i)    //nNum 括号个数//指向第几个括号        // ----- ②
        {//第一个括号已经初始化系数;//可以看出若取钱为num则第num+1个括号用不到
        //因为钱数连续为1、2、3、4...元
 
            for(j=0; j<=nNum; ++j)     //j是第一个括号里的每一项x^j的指数j
                for(k=0; k+j<=nNum; k+=i) //k相隔i;    //   k第二个括号的每一项x^k的指数
                { //比如说(1+x+x^2+...)(1+x^2+x^4+...)例如用1乘第二个括号内数
                //得到数的指数结果为1、2、4;所以k的下一个值就是k+=i
                    c2[j+k] += c1[j]; //目前的第一括号与第二括号两两相乘
                    //由于第二括号的系数全为1,相乘后的系数就是c1[j],累加即可
                }
            for(j=0; j<=nNum; ++j)     // 把c2中的值给c1,并把c2清0
            {
                c1[j] = c2[j];
                c2[j] = 0;
            }
        }
        cout << c1[nNum] << endl;//输出能组成nNum大小的方案数
    }
    return 0;
}


代码参考:https://blog.csdn.net/winter2121/article/details/55535894

当然上面的代码只是一个超级简单的模板,具体题目还要经过一定变动,但是理解了上面代码才能把变式题解决。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值