c++ std 方法 取两个数的较大_93、组合数学-不相邻的组合数-排座位例题

博客探讨了在C++中如何计算不相邻组合数,适用于取球问题和圆桌上不相邻座位的就坐安排。当n小于2r-1时,取法为0;当n大于等于2r-1时,取法为C(n-r+1,r)。对于围成一圈的情况,当n小于2r时,取法为0;当n大于等于2r时,取法为C(n-r,r)n/(n-r)。最后给出了一个具体的餐厅就坐问题,要求m个人在n个座位上不相邻就坐的方案数计算方法。" 77587894,1009978,ChatGirl:TensorFlow Seq2Seq 聊天机器人实践,"['聊天', '机器学习', 'TensorFlow', '自然语言处理', '数据集']
摘要由CSDN通过智能技术生成

参考:

组合数学--不相邻的组合数_MatstanLy_的博客-CSDN博客​blog.csdn.net
41169208d18f216868bafc27bd394cfa.png

一、从n个球中选出r个球,要求这r个球互不相邻,有多少种取法?

分析:①当n<2r-1时,取法为0种
例如4个球里取3个互不相邻的球,找不到这样的组合②n≥2r-1时,取法为C(n-r+1,r)种
这里考虑逆向思维。假设我们先从n-r+1个球中任意取r个球,组合数为C(n-r+1,r),然后再另外拿r-1个球插到那r个球的r-1个空位中,这样使得我们原本取出的r个球都互不相邻,并且最后总球数为n个。不难验证逆向思维得出的情况与正常考虑的情况是一一对应的,故我们可以得到上面的结论。
(临界情况:n=2r-1时,比如5个里取3个,7个里取4个,此时恰好只有C(n-r+1,r)=C(r,r)=1种取法)

二、从围成一圈的n个球中选出互不相邻的r个球有多少种不同的选法?

分析:①当n<2r时,取法为0种
例如4个球围一圈,选互不相邻的3个球,找不到这样的组合①当n>=2r时,取法为C(n-r,r)n/(n-r)种
首先对球进行编号,1号~n号,对于任何可能的组合,都只有两种情况:包含1号球的和不包含1号球的。

r个球包含1号球:首先选出1号球,然后需要从3号球~n-1号球取出r-1个互不相邻的球,根据上面那道题的结论,我们可以得到组合数为C(n-3-(r-1)+1,r-1)=C(n-r-1,r-1);

r个球里不包含1号球:我们需要从2号球~n号球取出r个互不相邻的球,其组合数为C(n-1-r+1,r)=C(n-r,r)

综上,总数为C(n-r-1,r-1)+C(n-r,r)=C(n-r,r)n/(n-r)
(临界情况:当n=2r时,例如4个取2个,6个取3个,共有C(r,r)*2r/r=2种)

(r/(n-r)) * C(n-r-1,r-1)= C(n-r,r)

题目:

餐厅里有一张圆形的桌子,桌子上有n个座位,座位按照顺序从1到n编号,而且n号座位和1号座位相邻,每个座位都不一样。m个人一起去这家餐厅吃饭。为了更好地就餐,他们不想坐得太过拥挤,因此,不允许有任意两个人相邻。

你知道一共有多少种不同的就坐方法吗?最后答案可能非常大,输出答案除以1000000007之后的余数。两种坐法不一样当且仅当存在一个人,在两种坐法中他坐在了不同的位置上。

输入:第一行一个数字T(T<=10)表示测试数据的组数。对于每组测试数据,输入两个数n和m(1<=n,m<=100000)。

4

3 1

3 2

4 2

50 10

输出: 每组数据输出一行,就坐的方案数,如果不存在合法的就坐方案,方案数为0。

3

0

4

128093084

思路:

第二种情况的全排列。

C(n-r,r)*(n/(n-r))*r! = n*[n-(r+1)]!/[n-2*r]!

#include<bits/stdc++.h>
using namespace std;
int main(){
    int T;cin>>T;
    while(T--){
        int n,m; cin>>n>>m;
        if(n<2*m){
            int tmp=0; cout<<tmp<<endl;
        }
        else{
            long long ans=n;
            for(int i=m+1; i<=2*m-1; i++)
                ans=ans*(n-i)%1000000007;
            cout<<ans<<endl;
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值