zoukankan      html  css  js  c++  java
  • HDU 1521 排列组合 (母函数)

    题目链接

    Problem Description

    有n种物品,并且知道每种物品的数量。要求从中选出m件物品的排列数。例如有两种物品A,B,并且数量都是1,从中选2件物品,则排列有"AB","BA"两种。

    Input

    每组输入数据有两行,第一行是二个数n,m(1<=m,n<=10),表示物品数,第二行有n个数,分别表示这n件物品的数量。

    Output

    对应每组数据输出排列数。(任何运算不会超出2^31的范围)

    Sample Input`

    2 2

    1 1`

    Sample Output

    2

    首先补充一下母函数的基本知识:
    对于某个数列的母函数是一种形式幂级数,其每一项的系数可以提供关于这个序列的信息。母函数主要应用于求解组合数、排列数、递推关系通项公式等。

    对于这个多项式乘法:

    可以得出的结论有:

    1. x的系数是a1,a2,…an的单个组合的全体

    2. x^2的系数是a1,a2,…an的两个组合的全体

    3. ·······
      n .x^n的系数是a1,a2,….an的n个组合的全体(只有1个)

      进一步可以得到:

      我们定义母函数

      对于序列a0,a1,a2,…构造一函数:

      称函数G(x)是序列a0,a1,a2,…的母函数。

      第一种例子分析:

      有1克、2克、3克、4克的砝码各一枚,能称出哪几种重量?每种重量各有几种可能方案?

      考虑用母函数来解决这个问题:

      我们假设x表示砝码,x的指数表示砝码的重量,这样:

      1个1克的砝码可以用函数1+1*x^1表示,

      1个2克的砝码可以用函数1+1*x^2表示,

      1个3克的砝码可以用函数1+1*x^3表示,

      1个4克的砝码可以用函数1+1*x^4表示,

      我们拿1+x^2来说,前面已经说过,x表示砝码,x的指数表示砝码的重量!初始状态时,这里就有一个质量为2的砝码。

      那么前面的1表示什么?按照上面的理解,1其实应该写为:1*x^0,即1代表重量为2的砝码数量为0个。

      所以这里1+1x^2 = 1x^0 + 1x^2,即表示2克的砝码有两种状态,不取或取,不取则为1x^0,取则为1*x^2

      把组合问题的加法法则和幂级数的乘幂对应起来

      对于1+x^2,讨论x前面的系数的意义?

      这里的系数表示状态数(方案数)

      1+x^2,也就是1x^0 + 1x^2,也就是上面说的不取2克砝码,此时有1种状态;或者取2克砝码,此时也有1种状态。(分析!)

      所以,前面说的那句话的意义大家可以理解了吧?

      几种砝码的组合可以称重的情况,可以用以上几个函数的乘积表示:

      (1+x)(1+x^2)(1+x^3)(1+x^4)

      =(1+x+x^2+x^4)(1+x^3+^4+x^7)

      =1 + x + x^2 + 2x^3 + 2x^4 + 2x^5+ 2x^6 + 2*x^7 + x^8 + x^9 + x^10

      从上面的函数知道:可称出从1克到10克,系数便是方案数。(!!!经典!!!)

      例如右端有2^x^5 项,即称出5克的方案有2种:5=3+2=4+1;同样,6=1+2+3=4+2;10=1+2+3+4。

      故称出6克的方案数有2种,称出10克的方案数有1种 。

      第二种例子分析

      求用1分、2分、3分的邮票贴出不同数值的方案数:

      大家把这种情况和第一种比较有何区别?第一种每种是一个,而这里每种是无限的。

      以展开后的x^4为例,其系数为4,即4拆分成1、2、3之和的拆分方案数为4;

      即 :4=1+1+1+1=1+1+2=1+3=2+2

      这里再引出两个概念"整数拆分"和"拆分数":

      所谓整数拆分即把整数分解成若干整数的和(相当于把n个无区别的球放到n个无标志的盒子,盒子允许空,也允许放多于一个球)。

      整数拆分成若干整数的和,办法不一,不同拆分法的总数叫做拆分数。

      下面是指数型母函数的定义:

    对于上面的问题“假设有8个元素,其中a1重复3次,a2重复2次,a3重复3次。从中取r个组合,求其组合数。”:

    (感谢 3Dnn 同学指出,下图的 28/3! 应该改为 26/3!)

    本题就是指数型母函数的代表

    题目分析

    对于给出的n中物品,每种物品的个数给出,求从中取出m件物品构成的排列数

       #include<stdio.h>
       #include<string.h>
       int jc[11]= {1,1,2,6,24,120,720,5040,40320,326880,3268800};
                  ///数组用于存储从0到10的阶乘
       int num[12];
       double c1[110],c2[110];
       int main()
       {
           int n,m;
           while(~scanf("%d%d",&n,&m))
           {
               memset(c1,0,sizeof(c1));
               memset(c2,0,sizeof(c2));
               for(int i=1; i<=n; i++)
               {
                   scanf("%d",&num[i]);
               }
               for(int i=0; i<=num[1]; i++)
               {
                   c1[i]=1.0/jc[i];///计算第一种物品存在不同个数的组合数
               }
    
               for(int i=2; i<=n; i++)///下面从第二种物品开始
               {
                   for(int j=0; j<=m; j++)///目前已经存在的物品数,肯定小于m
                   {
                       for(int k=0; k<=num[i]&&k<=m; k++)///要从当前的第i种物品中取出来的个数
                           c2[j+k]+=c1[j]/jc[k];///最终形成的一个排列数
                   }
                   for(int j=0; j<=m; j++)
                   {
                       c1[j]=c2[j];///c1存储的是最终的确定值,c2在刷新计算
                       c2[j]=0;
                   }
               }
               printf("%.0lf
    ",jc[m]*1.0*c1[m]);
    
           }
       }
  • 相关阅读:
    java.lang.NoSuchMethodError
    asm相关内容想下载(包括 jar 包)
    Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/objectweb/asm/Type
    用Navicat连接mysql报错:2003-Can't connect to MySql server on '10.100.0.109'(10039)
    The type java.lang.reflect.AnnotatedElement cannot be resolved. It is indirectly referenced from required .class files
    The type java.lang.CharSequence cannot be resolved. It is indirectly referenced from required .class files
    交通测速方式
    卡口和电子警察的区别
    Myeclipse连接Mysql数据库时报错:Error while performing database login with the pro driver:unable
    在window上安装mysql
  • 原文地址:https://www.cnblogs.com/cmmdc/p/6729699.html
Copyright © 2011-2022 走看看