组合数学--母函数

模板:(转载:https://blog.csdn.net/xiaofei_it/article/details/17042651

//为计算结果,b为中间结果。
int a[MAX],b[MAX];
//初始化a
memset(a,0,sizeof(a));
a[0]=1;
for (int i=1;i<=17;i++)//循环每个因子
{
    memset(b,0,sizeof(b));
    for (int j=n1[i];j<=n2[i]&&j*v[i]<=P;j++)//循环每个因子的每一项
        for (int k=0;k+j*v[i]<=P;k++)//循环a的每个项
            b[k+j*v[i]]+=a[k];//把结果加到对应位
    memcpy(a,b,sizeof(b));//b赋值给a
}
//模板二
//
初始化a,因为有last,所以这里无需初始化其他位 a[0]=1; int last=0; for (int i=0;i<K;i++) { int last2=min(last+n[i]*v[i],P);//计算下一次的last memset(b,0,sizeof(int)*(last2+1));//只清空b[0..last2] for (int j=n1[i];j<=n2[i]&&j*v[i]<=last2;j++)//这里是last2 for (int k=0;k<=last&&k+j*v[i]<=last2;k++)//这里一个是last,一个是last2 b[k+j*v[i]]+=a[k]; memcpy(a,b,sizeof(int)*(last2+1));//b赋值给a,只赋值0..last2 last=last2;//更新last }

HDU:1085

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int inf=0x3f3f3f3f;
int a[maxn],b[maxn];
int n2[maxn];
int v[maxn]={0,1,2,5};
int n1[]={0,0,0,0};
int p,K;
void muhs2(){
    a[0]=1;
    int last=0;
    for(int i=1;i<=3;i++){
        int last2=last+n2[i]*v[i];
        memset(b,0,sizeof(int)*(last2+1));
        for(int j=n1[i];j<=n2[i];j++){
            for(int k=0;k<=last;k++){
                b[k+j*v[i]]+=a[k];
            }
        }
        memcpy(a,b,sizeof(int)*(last2+1));
        last=last2;
    }
}
int main(){
    while(cin>>n2[1]>>n2[2]>>n2[3]){
        if(n2[1]+n2[2]+n2[3]==0)break;
        memset(a,0,sizeof(a));
        muhs2();
        int i=1;
        while(a[i]){
            i++;
        }
        cout<<i<<endl;
    }

    return 0;
}
View Code

 HDU:1171

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e6+10;
const int inf=0x3f3f3f3f;
int a[maxn],b[maxn];
int n2[maxn];
int v[maxn];
int n1[maxn]={0};
int n,p;
void muhs2(){
    a[0]=1;
    int last=0;
    for(int i=1;i<=n;i++){
        int last2=last+n2[i]*v[i];
        memset(b,0,sizeof(int)*(last2+1));
        for(int j=n1[i];j<=n2[i];j++){
            for(int k=0;k<=last;k++){
                b[k+j*v[i]]+=a[k];
            }
        }
        memcpy(a,b,sizeof(int)*(last2+1));
        last=last2;
    }
    int i=last/2;
    while(a[i]==0&&i>=0)i--;
    cout<<last-i<<' '<<i<<endl;
}
int main(){
    while(cin>>n){
        if(n<=0)break;
        memset(a,0,sizeof(a));
        for(int i=1;i<=n;i++){
            cin>>v[i]>>n2[i];
        }
        muhs2();
    }

    return 0;
}
View Code

HDU:1398

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e4+10;
const int inf=0x3f3f3f3f;
int a[maxn],b[maxn];
int n2[maxn];
int v[maxn];
int n1[maxn]={0};
int n,p;
void muhs1(){
    memset(a,0,sizeof(a));
    a[0]=1;
    for(int i=1;i<=17;i++){
        memset(b,0,sizeof(b));
        for(int j=0;j*v[i]<=n;j++){
            for(int k=0;k+j*v[i]<=n;k++){
                b[k+j*v[i]]+=a[k];
            }
        }
        memcpy(a,b,sizeof(b));
    }
    cout<<a[n]<<endl;
}
void init(){
    for(int i=1;i<=17;i++)v[i]=i*i;
}
int main(){
    init();
    while(cin>>n){
        if(n==0)break;
        memset(a,0,sizeof(a));
        muhs1();
    }

    return 0;
}
View Code

HDU:2079

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e4+10;
const int inf=0x3f3f3f3f;
int a[maxn],b[maxn];
int n2[maxn];
int v[maxn];
int n1[maxn]={0};
int n,m,p;
void muhs1(){
    memset(a,0,sizeof(a));
    a[0]=1;
    for(int i=1;i<=m;i++){
        memset(b,0,sizeof(b));
        for(int j=0;j*v[i]<=n&&j<=n2[i];j++){
            for(int k=0;k+j*v[i]<=n;k++){
                b[k+j*v[i]]+=a[k];
            }
        }
        memcpy(a,b,sizeof(b));
    }
    cout<<a[n]<<endl;
}
int main(){
    int T;
    cin>>T;
    while(T--){
        cin>>n>>m;
        for(int i=1;i<=m;i++){
            cin>>v[i]>>n2[i];
        }
        muhs1();
    }

    return 0;
}
View Code

HDU:2082

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e4+10;
const int inf=0x3f3f3f3f;
int a[maxn],b[maxn];
int n2[maxn];
int v[maxn];
int n1[maxn]={0};
int n,m,p=50;
void muhs1(){
    memset(a,0,sizeof(a));
    a[0]=1;
    for(int i=1;i<=26;i++){
        memset(b,0,sizeof(b));
        for(int j=0;j*v[i]<=p&&j<=n2[i];j++){
            for(int k=0;k+j*v[i]<=p;k++){
                b[k+j*v[i]]+=a[k];
            }
        }
        memcpy(a,b,sizeof(b));
    }
}
int main(){
    int T;
    cin>>T;
    while(T--){
        for(int i=1;i<=26;i++){
            v[i]=i;
            cin>>n2[i];
        }
        muhs1();
        ll ans=0;
        for(int i=1;i<=50;i++){
            ans+=a[i]*1LL;
        }
        cout<<ans<<endl;
    }

    return 0;
}
View Code

HDU:2110

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int inf=0x3f3f3f3f;
int a[maxn],b[maxn];
int n2[maxn];
int v[maxn];
int n1[maxn]={0};
int n,m,p=50,sum;
void muhs1(){
    a[0]=1;
    int last=0;
    for(int i=1;i<=n;i++){
        int last2=min(last+n2[i]*v[i],sum);
        memset(b,0,sizeof(int)*(last2+1));
        for(int j=0;j<=n2[i]&&j*v[i]<=last2;j++){
            for(int k=0;k<=last&&k+j*v[i]<=last2;k++){
                b[k+j*v[i]]+=a[k];
                b[k+j*v[i]]%=10000;
            }
        }
        memcpy(a,b,sizeof(int)*(last2+1));
        last=last2;
    }
    if(a[sum]>0)cout<<a[sum]%10000<<endl;
    else cout<<"sorry"<<endl;
}
int main(){
    while(cin>>n){
        if(n==0)break;
        memset(a,0,sizeof(a));
        sum=0;
        for(int i=1;i<=n;i++){
            cin>>v[i]>>n2[i];
            sum+=(v[i]*n2[i]);
        }
        if(sum%3){
            cout<<"sorry"<<endl;
            continue;
        }
        sum/=3;
        muhs1();
    }

    return 0;
}
View Code

HDU:2152

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+10;
const int inf=0x3f3f3f3f;
int a[maxn],b[maxn];
int n2[maxn];
int v[maxn];
int n1[maxn];
int n,m,p=50;
void muhs1(){
    a[0]=1;
    int last=0;
    for(int i=1;i<=n;i++){
        int last2=min(last+n2[i]*v[i],m);
        memset(b,0,sizeof(int)*(last2+1));
        for(int j=n1[i];j<=n2[i]&&j*v[i]<=last2;j++){
            for(int k=0;k<=last&&k+j*v[i]<=last2;k++){
                b[k+j*v[i]]+=a[k];
            }
        }
        memcpy(a,b,sizeof(int)*(last2+1));
        last=last2;
    }
    if(last<m)cout<<0<<endl;
    else cout<<a[m]<<endl;
}
int main(){
    while(cin>>n>>m){
        for(int i=1;i<=n;i++){
            v[i]=1;
            cin>>n1[i]>>n2[i];
        }
        muhs1();

    }

    return 0;
}
View Code

 HDU:1284

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+10;
const int inf=0x3f3f3f3f;
int a[maxn],b[maxn];
int n2[maxn];
int v[maxn]={0,1,2,3};
int n1[maxn];
int n,m,p=50;
void muhs1(){
    a[0]=1;
    n=32768;
    int last=0;
    for(int i=1;i<=3;i++){
        int last2=n;
        memset(b,0,sizeof(int)*(last2+1));
        for(int j=0;j*v[i]<=last2;j++){
            for(int k=0;k<=last&&k+j*v[i]<=last2;k++){
                b[k+j*v[i]]+=a[k];
            }
        }
        memcpy(a,b,sizeof(int)*(last2+1));
        last=last2;
    }
}
int main(){
    muhs1();
    while(cin>>n){
        cout<<a[n]<<endl;
    }

    return 0;
}
View Code

 HDU:2189

#include <bits/stdc++.h>
using namespace std;
const int maxn=160;
int n,m;
int a[maxn],b[maxn];
int prime[maxn];
void getprime(){
    memset(prime,0,sizeof(prime));
    for(int i=2;i<=150;i++){
        if(!prime[i])prime[++prime[0]]=i;
        for(int j=1;j<=prime[0]&&prime[j]<=150/i;j++){
            prime[prime[j]*i]=1;
            if(i%prime[j]==0)break;
        }
    }
}
void muhs(){
    memset(a,0,sizeof(a));
    for(int i=0;i<=n;i+=2)a[i]=1;
    for(int i=2;i<=prime[0];i++){
        memset(b,0,sizeof(b));
        for(int j=0;j<=150;j++){
            for(int k=0;k+j<=n;k+=prime[i]){
                b[k+j]+=a[j];
            }
        }
        memcpy(a,b,sizeof(b));
    }

}
int main(){
    getprime();
    int T;
    cin>>T;
    while(T--){
        cin>>n;
        muhs();
        cout<<a[n]<<endl;
    }
}
View Code

HDU:2065

指数型母函数,根据泰勒展开(虽然还不懂……)最终答案为2^(n-1)+4^(n-1)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=160;
const int mod=100;
ll n;
int a[maxn],b[maxn];
ll ksm(ll a,ll b){
    ll ans=1;
    while(b){
        if(b&1){
            ans=(ans*(a%mod))%mod;
        }
        b>>=1;
        a=((a%mod)*(a%mod))%mod;
        ans%=mod;
    }
    return ans%mod;
}

int main(){
    int T;
    while(cin>>T){
        if(T==0)break;
        int flag=1;
        while(T--){
            cin>>n;
            cout<<"Case "<<flag++<<": ";
            cout<<(ksm(2,n-1)+ksm(4,n-1))%mod<<endl;
        }
        cout<<endl;
    }

}
View Code

 POJ:3734

跟上题一样,泰勒展开

#include <iostream>
using namespace std;
typedef long long ll;
const int maxn=160;
const int mod=10007;
ll n;
int a[maxn],b[maxn];
ll ksm(ll a,ll b){
    ll ans=1;
    while(b){
        if(b&1){
            ans=(ans*(a%mod))%mod;
        }
        b>>=1;
        a=((a%mod)*(a%mod))%mod;
        ans%=mod;
    }
    return ans%mod;
}

int main(){
    int T;
    cin>>T;
    while(T--){
        cin>>n;
        cout<<(ksm(2,n-1)+ksm(4,n-1))%mod<<endl;
    }

}
View Code

HDU:1709

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e4+10;
int n;
int a[maxn],b[maxn],v[maxn];
int ans[maxn];
int sum=0;
void muhs(){
    memset(a,0,sizeof(a));
    a[v[1]]=1;
    a[0]=1;
    for(int i=2;i<=n;i++){
        memset(b,0,sizeof(b));
        for(int j=0;j<=sum;j++){
            if(b[j]==1||a[j]==1)b[j]=1;
            if(a[j]==1)b[j+v[i]]=b[abs(j-v[i])]=1;
        }
        memcpy(a,b,sizeof(b));
    }
    /*for(int i=1;i<=sum;i++)cout<<a[i]<<' ';
    cout<<endl;*/
}
int main(){
    ios::sync_with_stdio(false);
    while(cin>>n){
        sum=0;
        for(int i=1;i<=n;i++){
            cin>>v[i];
            sum+=v[i];
        }
        muhs();
        int tot=0;
        for(int i=1;i<=sum;i++){
            if(a[i]==0){
                ans[tot++]=i;
            }
        }
        cout<<tot<<endl;
        for(int i=0;i<tot;i++){
            if(i==tot-1)cout<<ans[i]<<endl;
            else cout<<ans[i]<<' ';
        }
    }

}
View Code

HDU:1261(JAVA)多重集的排列

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner scn = new Scanner(System.in);
        int n;
        int a[]=new int [27];
        while(scn.hasNextInt()){
            n=scn.nextInt();
            if(n==0)break;
            int sum=0;
            for(int i=1;i<=n;i++){
                a[i]=scn.nextInt();
                sum+=a[i];
            }
            BigInteger ans=BigInteger.ONE;
            for(int i=1;i<=sum;i++){
                ans=ans.multiply(BigInteger.valueOf(i));
            }
            BigInteger ansm=BigInteger.ONE;
            for(int i=1;i<=n;i++){
                int x=1;
                for(int j=1;j<=a[i];j++){
                    x*=j;
                }
                ansm=ansm.multiply(BigInteger.valueOf(x));
            }
            System.out.println(ans.divide(ansm));
        }

    }
}
View Code

HDU:1028

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e4+10;
int n;
int a[maxn],b[maxn];
void muhs(){
    memset(a,0,sizeof(a));
    for(int i=0;i<=n;i++)a[i]=1;
    for(int i=2;i<=n;i++){
        memset(b,0,sizeof(b));
        for(int j=0;j<=n;j++){
            for(int k=0;k<=n&&j+k<=n;k+=i){
                b[j+k]+=a[j];
            }
        }
        memcpy(a,b,sizeof(b));
    }
}
int main(){
    while(cin>>n){
        muhs();
        cout<<a[n]<<endl;
    }


    return 0;
}
View Code

 HDU:2069(二维母函数)控制了硬币的数量

#include <bits/stdc++.h>
using namespace std;
const int maxn=310;
int n;
int a[maxn][105],b[maxn][105];
int v[10]={1,5,10,25,50};
void muhs(){
    memset(a,0,sizeof(a));
    for(int i=0;i<=100;i++)a[i][i]=1;
    for(int i=1;i<5;i++){
        memset(b,0,sizeof(b));
        for(int j=0;j<=n;j++){
            for(int k=0;k+j<=n;k+=v[i]){
                for(int kk=0;kk+k/v[i]<=100;kk++){
                    b[k+j][kk+k/v[i]]+=a[j][kk];
                }
            }
        }
        for(int j=0;j<=n;j++){
            for(int k=0;k<=100;k++){
                a[j][k]=b[j][k];
                b[j][k]=0;
            }
        }
    }
}


int main(){
    while(cin>>n){
        muhs();
        int ans=0;
        for(int i=0;i<=100;i++)ans+=a[n][i];
        cout<<ans<<endl;
    }

    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/lin1874/p/11382708.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值