算法数学基础-排列组合(题目取自牛客网)

基础理论:

  1. 排列

有限集的子集按某种条件的序化法排成列、排成一圈、不许重复或许重复等。
从n个不同元素中每次取出m(1≤m≤n)个不同元素,排成一列,称为从n个元素中取出m个元素的无重复排列或直线排列,简称排列
在这里插入图片描述
五个字母全排列有5!=120

  1. 组合

从n个不同元素中每次取出m个不同元素(0≤m≤n),不管其顺序合成一组,称为从n个元素中不重复地选取m个元素的一个组合。
所有这样的组合的总数称为组合数,这个组合数的计算公式为:
在这里插入图片描述

1、对于相同元素的有序分组问题(利用隔板法)

参考博客:http://www.sohu.com/a/230556468_301997

【例1】现有7个完全相同的小球,将它们全部放入编号为1,2,3,4的四个盒子中,每个盒子至少放一个球,问有多少种不同的放法?

【思路点拨】这道题满足隔板法基本模型的三大条件(1.有若干个相同的元素;2. 将元素有序分组,每组至少有一个元素;2. 元素不能有剩余),所以我们可以直接应用隔板法。首先我们将7个小球排成一排。在7个小球中间一共有6个间隔,在这6个间隔中我们挑出3个间隔插入隔板,这样我们就将小球分成了四份,并且每一份都至少有一个小球。接着我们将这四份小球按从左到右的顺序依次放入1-4号四个盒子中,就得到了对应的一种放法。这样一来,每一种隔板的插法就对应了一种小球的方法。6个间隔中插入3个隔板的插法共20种,即本题共有20种不同的放法。

【方法总结】将个相同的元素有序的放入个盒子中(不允许空盒),相当于在个间隔中插入个隔板,因此不同的放法与不同的隔板插法种数相同,共有种放法。这里的是组合数种的基本公式,其计算公式为【 组合C(n,m)=P(n,m)/P(m,m) =n!/m!(n-m)!】。

n=6,m=3

2、变式(1):受限制分组问题

【例2】现有12个完全相同的小球,将它们全部放入编号为1,2,3,4的四个盒子中,每个盒子至少放两个球,问有多少种不同的放法?

【思路点拨】每个盒子我只要至少放一个球就可以啦。也就是说只要让每个盒子里提前都装入一个球,那就可以用隔板法。
所以先拿出4个球,分别装入四个盒中,现在每个盒子里都有1个球了!这样一来问题就变成了将剩下8个相同的球,有序地装入四个盒子中,每个盒子中至少放入1个球,有多少种放法?这还不简单,直接应用刚才基本隔板法模型的结论,在7个间隔中插入3个隔板。

【方法总结】本题为隔板法的变式,原理在于需要先在每个盒子中放入一定数量的小球,再转化为隔板法的基本模型。总结如下:将个相同的元素有序的放入个盒子中(每个盒子中至少放入个元素,),需要先在每个盒子中放入个元素,再将剩余元素利用隔板法放入个盒子中

n=7 m=3

【例3】现有12个相同的小球,将它们全部放入编号为1,2,3,4的四个盒子中,要求每个盒子中的小球个数不小于其编号数,问不同的放法有多少种?

【思路点拨】这道题和例2有些类似,必须要先在某些盒子中放入某个数量的小球,才能转化为隔板法解决。比如2号盒子中最终至少要有2个小球,所以考试君在2号盒子中先放入1个球。同理在3号盒子中先放入2个球,4号盒子中先放入3个球。这样保证每个盒子中只需要再至少放入1个球就可以达到要求。故对剩余6个球用隔板法放入四个盒子中.

【方法总结】本题同样为隔板法的变式,总结如下:当每个盒子均不是空盒且元素数量要求不同时,我们需要先放入一定数量的元素,使得每个盒子中只需要再至少放入1个元素就可以达到要求。再对剩余的元素利用隔板法放入盒子中。

n=5,m=3;

【例4】现有8个完全相同的小球,将它们全部放入编号为1,2,3的三个盒子中,允许出现空盒,问有多少种不同的放法?

【思路点拨】我们先借3个球(有多少个盒子借多少个),让我用隔板法分个球”。成功地借到了3个球之后,这时候我们就可以这样来操作。加上原来地8个球,现在共有11个球,利用隔板法将它们放到三个盒子中,共有种放法。对于每一种放法,考试君都从每个盒子中拿出一个球还回去。当盒中分到一个球之后还回1个球,该盒实际上是空盒;分到两个球后还回1个球,该盒实际上只含一个球,依此类推。这样就成功地将8个相同的小球分入了三个盒中,允许有空盒的共有45种放法。

【方法总结】将个相同的元素有序的放入个盒子中(允许空盒),需要先通过外部力量另外借到个相同的元素,转化为将个元素用隔板法放入个盒子中(最后每个盒子都拿出一个球还回去),所以共有种放法。

n=10,m=3

编程例题
将20个球放进12个不同的袋子,每个袋子可以放0-20个球,有多少种放法?分析如何计算,然后编程解答。

进阶问题:每个袋子只能放0个、2个或3个球,该如何计算?

链接:https://www.nowcoder.com/questionTerminal/b01b4a95413040eaa1effbd34280c78c
来源:牛客网

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
//        写入球的个数
         int ball;
//        写入袋子的个数
         int pack;
         Scanner scan = new Scanner(System.in);
         System.out.println("请输入球的个数");
         ball = Integer.parseInt(scan.next());
         System.out.println("袋子个数");
         pack = Integer.parseInt(scan.next());
         System.out.println(getban(ball, pack));
         
    }
    
    
//    隔板法
    public static long getban(int ball,int pack)
    {
//        由于无法保证每个袋子都能装上一个球,无法使用隔板法,
//        所以故意往每个袋子加1个球,当排序的时候可以往每个袋子里减一个球就可以了
        long result = 1;
        int newball = ball + pack;
//        所以每个球的空隙有newball -1个
        int newballair = newball -1;
//        因为需要放入12-1个袋子(插入12-1块板),所以用公式C(newballair,pack-1)
        /*
         * C(m,n) = m!/n!*(m-n)!
         */
        for(int i = newballair - (pack - 1) + 1; i <= newballair ; i++)
        {
            result *= i; 
        }
        return result / factorial(pack-1);
    }
    
//    阶乘方法
    public static long factorial(int num)
    {
        if(num == 1)
        {
            return 1;
        }
        else
        {
            return num * factorial(num-1);
        }
    }
}

例题2:五个球从盒子里拿出来,打乱顺序放回去,均不在原位的排列数是多少()

思路:首先我们可以把五个球看成abcde,然后分为以下五种情况来排列

  1. 首先,a放在任意位置(想象成a右移),则有四种不同的排列
  2. a占b的位置,则cde有两种排列方式,分别是ecd和dec(e的两次右移)
  3. a不占b的位置(a,b不交换位置),B的位置没有被A占:则B的位置有3种选择,C的位置有3种选择(因为A在这3个里面,A无论在CDE的哪个位置上,都没有问题,只要A的位置定了,另外两个的位置肯定也定了,因为它们只能交换位置),所以是 3*3种

概率题
https://www.asklib.com/view/12798def.html

例子:
1000个钱币中有10个金币,取一次钱币是金币的概率为0.1,取两次呢,取n次呢

思路:求得每次取不到的概率,用1减去这个概率即可。

dp[n]=990-(n-1)/1000-(n-1) *dp[n-1],dp[0]=1
最终结果1-dp[n]

发布了36 篇原创文章 · 获赞 11 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/s_xchenzejian/article/details/102482037