C++进阶课程第2期——排列与组合1

大家好,我是清墨,欢迎收看《C++进阶课程——排列与组合》。

 啊,上一期我们的情况啊也是非常好的,今天直接开始!

排列(Arrange)

与上期一样啊,我们先了解一下排列的概念。 

排列是指将一组事物按照一定的顺序进行摆放的方式。在数学中,排列是指从一组事物中选取若干个进行组合,并按照特定的顺序进行排列的方法。

至于怎样表示呢就用A_{n}^{m}表示从n个元素中选择m个元素进行排列,所有的方案数。

A_{n}^{n}是n的全排列,结果是n的阶乘(n!)。

计算:A_{n}^{m}     =     \frac{n!}{(n-m)!}

组合(Combination)

组合是从给定的元素集合中选取一些元素的方式。在组合中,选取的元素的顺序是不重要的,也就是说,(1,2,3)和(3,2,1)被视为相同的组合。 

至于怎样表示呢就用C_{n}^{m}表示从n个元素中选择m个元素进行组合,所有的方案数。

计算:C_{n}^{m} = \frac{n!}{m!\cdot (n-m)!}

海题——杨辉三角

题目描述

1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1

上面的图形熟悉吗?如果还没看出来它的特点的话,不妨再调整一下格式:

     1
    1 1
   1 2 1
  1 3 3 1
 1 4 6 4 1
1 5 10 10 5 1

是不是看出这些数字的特点了?这是大名鼎鼎的杨辉三角。

今天,我们试着来输出 n 行的杨辉三角数字。

输入格式 1 个正整数:n。

输出格式 相应层数的杨辉三角数字。

样例

输入数据 1

6

输出数据 1

1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1

 

代码:

#include<bits/stdc++.h>
using namespace std;
int n,a[111][111];
int main(){
    cin>>n;
    a[1][1]=1;
    a[2][1]=1;
    a[2][2]=1;
    for(int i=3;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            a[i][j]=a[i-1][j]+a[i-1][j-1];
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=i;j++)
        {
            cout<<a[i][j]<<" ";
        }
        cout<<endl;
    }
    return 0;
}

 杨辉三角有什么用呢,先买个管子,进入例题。

例题1.派水果

 题目描述

若一位母亲手里有 m 个相同的苹果,还有 n 个相同的梨,在 m+n 天内分给她的小孩,每天分 1 个水果,有多少种不同的分派方案?。

输入格式 两个整数 m 和 n ( 1≤m,n≤32)。

输出格式 一个整数。结果不超出 max long long

样例

输入数据 1

2 3

输出数据 1

10

分析题目 

本题确定了苹果的位置就可以确定梨的位置,又因为苹果和梨都相同,所以不用考虑顺序。

只用求 C_{n+m}^{m}或  C_{n+m}^{n}就可以了。

所以C_{n+m}^{m}=C_{n+m}^{n}

但是,直接计算必须会超,在我们计算32的阶乘时,就会溢出。

“e+35”!10的35次方,超出了long long范围,那要怎样计算呢?

找规律 

我们不妨试试小点的C。

用原本的代码计算小一点的。

#include<bits/stdc++.h>
using namespace std;
long long ans1=1,ans2=1,n,m;
int main(){
    cin>>n>>m;
    n+=m;
    for(long long i=n;i>=n-m+1;i--)
    {
        ans1*=i;
    }
    for(long long i=m;i>=1;i--)
    {
        ans2*=i;
    }
    cout<<ans1/ans2;
    return 0;
}

得 :

C_{0}^{0}=1

C_{1}^{1}=1 

C_{2}^{1}=2 C_{2}^{2}=1

C_{3}^{1}=3 C_{3}^{2}=3 C_{3}^{3}=1

C_{4}^{1}=4 C_{4}^{2}=6 C_{4}^{3}=4C_{4}^{4}=1

有点感觉了吗?

1
1         1
1         2 1
1         3 3 1
1         4 6 4 1

杨辉三角!

代码

写得代码

#include<bits/stdc++.h>
using namespace std;
long long n,a[11100][11000],m;
int main(){
    cin>>n>>m;
    n+=m;
    a[1][1]=1;
    a[1][2]=1;
    for(int i=2;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            a[i][j]=a[i-1][j]+a[i-1][j-1];
        }
    }
    cout<<a[n][n-m+1];
    return 0;
}

所以杨辉三角可不只是数学游戏和海题,在实际应用中有大用。例如在计算组合方案数的时候,C(n, m) = C(n-1,m) + C(n-1, m-1),从而避免了组合公式中的除法运算(除法运算的计算机代码要复杂很多,远远没有加法容易处理)。

我们下期再见。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值