数学、生成函数

对数量为 $n$,重量为 $w$ 的砝码构造生成函数

$$f(w,n)=1+x^{w}+x^{2w}+x^{3w}+ \cdots + x^{nw}$$

构造完成后将所有重量的砝码对应的生成函数相乘得到 $F(x)$,令 $F(x)$ 的 $i$ 次项系数为 $k_i$,这些砝码有 $k_i$ 种凑出重量 $i$ 的方案,答案为 $\sum\limits_{i=1}^{\infty} [k_i \neq 0]$。

#include<bits/stdc++.h>
using namespace std;
constexpr int S[]={0,1,2,3,5,10,20};
template<typename T>
struct Poly{
    int len;T f[2005];
    Poly(){len=0,memset(f,0,sizeof(f));}
    Poly operator*(const Poly<T> &x)const{
        Poly<T> ret;
        ret.f[0]=f[0]*x.f[0];
        for(int i=1;i<=len;i++) ret.f[i]+=f[i]*x.f[0];
        for(int i=1;i<=x.len;i++) ret.f[i]+=f[0]*x.f[i];
        for(int i=1;i<=len;i++)
            for(int j=1;j<=x.len;j++)
                ret.f[i+j]+=f[i]*x.f[j];
        ret.len=len+x.len;
        while(ret.len&&!ret.f[ret.len]) ret.len--;
        ret.len=max(ret.len,1);
        return ret;
    }
};
Poly<int> pol;
int ans,opt;
int main(){
    pol.len=0,pol.f[0]=1;
    for(int i=1;i<=6;i++){
        scanf("%d",&opt);
        Poly<int> fio;
        fio.len=S[i]*opt;
        for(int j=0;j<=opt;j++) fio.f[j*S[i]]=1;
        pol=pol*fio;
    }
    for(int i=1;i<=pol.len;i++) if(pol.f[i]) ans++;
    printf("Total=%d\n",ans);
    return 0;
}
最后修改:2024 年 05 月 26 日
如果觉得我的文章对你有用,请随意赞赏