zoukankan      html  css  js  c++  java
  • 母函数 经典题目汇总

    HDU 1398 Square Coins(普通母函数 || 完全背包)

    题意:
    可选钱 种类17种,值分别为    i*i(i>=1&&i<=17)
    求组和之和=钱数K的方案数
     
     
    分析:
     
    方法一:
    ///DP   完全背包问题(求装入背包)
    ///f[i]表示
    ///打表
    #include<stdio.h>
    int main()
    {
        int a[20]={0,1,4,9,16,25,36,49,64,81,100,121,144,169,196,225,256,289},f[305]={0};
        int i,n,j;
        f[0]=1;
        for(i=1;i<=17;i++)///第几种钱
            for(j=a[i];j<=300;j++)///
                f[j]+=f[j-a[i]];
        while(scanf("%d",&n)!=EOF){
            if(n==0)
                break;
            printf("%d
    ",f[n]);
        }
        return 0;
    }

    方法二:

    母函数

    母函数应用于——————形式上说,普通型生成函数用于解决多重集的组合问题,而指数型母函数用于解决多重集的排列问题.。现在我们先讨论普通生成函数;

    这里组合问题,用普通母函数

    #include "cstdio"
    #define N 305
    int c1[N];///记录各次幂系数
    int c2[N];///记录中间计算结果
    void solve()
    {
        for(int i=0;i<=300;i++)///初始化(第一个表达式)
        {
            c1[i]=1;
            c2[i]=0;
        }
        for(int i=2;i<=17;i++)///那个表达式
        {
            for(int j=0;j<=300;j++)
            {
                for(int k=0;k+j<=300;k+=i*i)///此表达式中各项的次幂
                {                           ///(把组合问题的加法法则和幂级数的乘幂对应起来)
                    c2[j+k]+=c1[j];
                }
            }
            for(int j=0;j<=300;j++)
            {
                c1[j]=c2[j];
                c2[j]=0;
            }
        }
    }
    int main()
    {
        int n;
        solve();
        while(~scanf("%d",&n),n)
        {
            printf("%d
    ",c1[n]);
        }
        return 0;
    }

     HDU1028 

    Ignatius and the Princess III

    题意:

    输入一数N,求1-N N种数,任意组合(数不一定都出现和个数任意)之和=N的方案个数

    分析:

    组合问题

    普通母函数

    #include "cstdio"
    #define N 305
    int c1[N];
    int c2[N];
    void solve()
    {
        for(int i=0;i<=120;i++)
        {
            c1[i]=1;
            c2[i]=0;
        }
        for(int i=2;i<=120;i++)
        {
            for(int j=0;j<=120;j++)
            {
                for(int k=0;k+j<=120;k+=i)
                {
                    c2[k+j]+=c1[j];
                }
            }
            for(int j=0;j<=120;j++)
            {
                c1[j]=c2[j];
                c2[j]=0;
            }
        }
    }
    int main()
    {
        int n;
        solve();
        while(scanf("%d",&n)!=EOF)
        {
            printf("%d
    ",c1[n]);
        }
    }

    HDU1085
    题意:1 2 5三种数,你赋予他们数量,求他们组成和不能组成的最小数

    个数有限

    #include "cstdio"
    #include "iostream"
    #include "cstring"
    using namespace std;
    #define N 10000
    int c1[N];
    int c2[N];
    int num[4];
    int Max;
    void solve()
    {
        num[1]*=2;num[2]*=5;
        Max=num[0]+num[1]+num[2];
        memset(c1,0,sizeof(c1));
        memset(c2,0,sizeof(c2));
        for(int i=0;i<=num[0];i++)
        {
            c1[i]=1;
        }
        for(int j=0;j<=num[0];j++)
            for(int k=0;k+j<=num[0]+num[1];k+=2)
            c2[k+j]+=c1[j];
        for(int i=0;i<=num[0]+num[1];i++)
        {
            c1[i]=c2[i];c2[i]=0;
        }
        for(int j=0;j<=num[0]+num[1];j++)
            for(int k=0;k+j<=num[0]+num[1]+num[2];k+=5)
            c2[k+j]+=c1[j];
        for(int i=0;i<=num[0]+num[1]+num[2];i++)
        {
            c1[i]=c2[i];c2[i]=0;
        }
    }
    int main()
    {
        while(scanf("%d%d%d",&num[0],&num[1],&num[2])!=EOF&&(num[0]||num[1]||num[2]))
        {
            solve();
            int i;
            for(i=0;i<=Max;i++)
            {
                if(c1[i]==0)
                {
                    printf("%d
    ",i);
                    break;
                }
            }
            if(i==Max+1)
                printf("%d
    ",i);
        }
    }
  • 相关阅读:
    C++ Primer 随笔 Chapter 2 变量和基本类型
    比较全面的gdb调试命令 (转载)
    open和fopen的区别(转)
    来了
    Function语义学之member function
    TCP/IP学习(四)TCP缓冲区大小及限制(转)
    TCP连接的建立和终止
    Data 语义学(2)
    Data 语义学(1)
    一个类到底有多大?
  • 原文地址:https://www.cnblogs.com/kimsimple/p/6709060.html
Copyright © 2011-2022 走看看