组合数学

容斥原理

f ( S ) = ∑ T ⊆ S g ( T ) g ( S ) = ∑ T ⊆ S ( − 1 ) ∣ S ∣ − ∣ T ∣ f ( T ) f(S)=\sum_{T \subseteq S} g(T) \\ g(S)=\sum_{T \subseteq S}(-1)^{|S|-|T|} f(T) f(S)=TSg(T)g(S)=TS(1)STf(T)

母函数求组合数

超级易懂的link

题目

HDU 2082
直接把不同字母的多项式相乘就行,模板题
如只有2个a,3个c,1个g
( x 0 + x 1 + x 2 ) ( x 0 + x 3 + x 6 + x 9 ) ( x 7 ) (x^0+x^1+x^2)(x^0+x^3+x^6+x^9)(x^7) (x0+x1+x2)(x0+x3+x6+x9)(x7)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int num[30];  // 每个字母的数量
ll sup[55];
ll tmp[55];
int main(){
    int T;
    cin>>T;
    while(T--){
        for(int i=1;i<=26;++i){
            cin>>num[i];
            if(num[i]*i>50)num[i]=50/i;
        }
        memset(tmp,0,sizeof(tmp));
        memset(sup,0,sizeof(sup));
        sup[0] = 1;
        for(int i=1;i<=26;++i){
            for(int j=0;j<=num[i];++j){
                for(int k=0;j*i+k<=50;++k){
                    tmp[j*i+k] += sup[k];
                }
            }
            for(int j=0;j<=50;++j){
                sup[j] = tmp[j];
                tmp[j] = 0;
            }
        }
        ll ans = 0;
        for(int i=1;i<=50;++i)
            ans += sup[i];
        cout<<ans<<endl;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值