排队(排列组合)

题目大意:

两个老师,n个男,m个女,女不互邻,老师不互邻 方案

不是${A_n^n}*{A_{n+1}^m}*{A_{n+m+1}^2}$,也不是${A_n^n}*{A_{n+1}^2}*{A_{n+3}^m}$

因为这两种都没有考虑两个老师||两个女生互邻然后中间再插一个(挡板法默认不相邻)

首先用${A_{n+1}^{n+1}}$$*$  ${A_{n+2}^{m-1}}$$*m*2$求出老师老师之间插男生时情况

那么应该再加上两个老师之间插一个女生

首先默认两个老师相邻因为两个老师不同,所以有两种情况${A_2^2}$,然后中间塞一个女生有m种情况;

然后把“”老师“”--“”女生“”--“”老师“”看作一个组合体即看成一个男生

然后剩余m-1个女生往n+2个空里插

所得${A_{n+1}^{n+1}}$$*$$A_{n+2}^{m-1}$$*m*2$

最终相加得到$ans=$${A_n^n}*{A_{n+1}^2}*{A_{n+3}^m}$$+$${A_{n+1}^{n+1}}$$*$$A_{n+2}^{m-1}$$*m*2$

以下是本人丑陋的代码

  1 #include<bits/stdc++.h>
  2 #define ll long long
  3 #define N 10000
  4 #define P 4
  5 using namespace std;
  6 ll n,m;
  7 struct bignum
  8 {
  9     ll n[20000],l;
 10     bignum(){l=1,memset(n,0,sizeof(n));}
 11     void clear(){while(l>1&&!n[l-1]) l--;}
 12     void print()
 13     {
 14         printf("%lld",n[l-1]);
 15         for(ll i=l-2;i>=0;i--)
 16         printf("%0*lld",P,n[i]);
 17         printf("\n");
 18     }
 19     bignum operator = (ll x)
 20     {
 21         l=0;    
 22         while(x)
 23         {
 24             n[l++]=x%N;
 25             x/=N;
 26         }
 27         return *this;
 28     }
 29     bignum operator +(bignum x) const
 30     {
 31         bignum t=*this;
 32         if(x.l>t.l) t.l=x.l;        
 33         for(ll i=0;i<t.l;i++)
 34         {
 35             t.n[i]+=x.n[i];
 36             if(t.n[i]>=N)
 37             {
 38                 t.n[i+1]+=t.n[i]/N;
 39                 t.n[i]%=N;
 40             }
 41         }
 42         return t;
 43     }
 44        bignum operator * (const ll& b)
 45       {
 46             bignum c;
 47            c.l=0;
 48              for(ll i=0,g=0;g||i<l;i++)
 49             {
 50                 ll x;
 51             if(i<l)x=n[i]*b+g;
 52             else x=g;
 53             c.n[c.l++]=x%N;
 54             g=x/N;
 55         }
 56         return c;
 57         }
 58     bignum operator *(bignum x) const
 59     {
 60         bignum t=*this,tep;
 61         tep.l=t.l+x.l;
 62         for(ll i=0;i<t.l;i++)
 63             for(ll j=0;j<=x.l;j++)
 64             {
 65                 tep.n[i+j]+=t.n[i]*x.n[j];
 66             }
 67         for(ll i=0;i<tep.l;i++)
 68         {
 69             tep.n[i+1]+=tep.n[i]/N;
 70             tep.n[i]%=N;
 71         }
 72         tep.clear();
 73         return tep;
 74     }    
 75     bool operator <(bignum x) const
 76     {
 77         bignum t=*this,tep;
 78         if(t.l!=x.l)    return t.l<x.l;
 79         for(ll i=t.l-1;i>=0;i--)
 80         {
 81             if(t.n[i]!=x.n[i]) return t.n[i]<x.n[i];
 82         }
 83         return 0;
 84     }
 85     bool operator >(bignum x) const
 86     {
 87         bignum t=*this;
 88         if(t.l!=x.l) return t.l>x.l;
 89         for(ll i=t.l-1;i>=0;i--)
 90         {
 91             if(t.n[i]!=x.n[i]) return t.n[i]>x.n[i];
 92         }
 93         return 0;
 94     }
 95     bignum operator -(bignum x) const
 96     {
 97         bignum t=*this;
 98         if(t<x) printf("-");swap(t,x);
 99         ll jie=0;
100         for(ll i=0;i<t.l;i++)
101         {
102             t.n[i]-=x.n[i];
103             while(t.n[i]<0)
104             {
105                 t.n[i]+=N;
106                 jie++;
107             }
108             t.n[i+1]-=jie;
109             jie=0;
110         }
111         while(!t.n[t.l-1]&&t.l>1) t.l--;
112         return t;
113     }
114 
115 }ans,c;
116 bignum A(ll m,ll n)
117 {
118     bignum c;
119     c=1;
120     for(ll i=n-m+1;i<=n;i++)
121         c=c*i;
122     return c;
123 }
124 int main()
125 {
126     cin>>n>>m;
127     ans=0;
128     ans=A(n,n)*(A(2,n+1)*A(m,n+3)+A(1,n+1)*A(2,2)*A(1,m)*A(m-1,n+2));
129     ans.print();
130 }
View Code

 

转载于:https://www.cnblogs.com/znsbc-13/p/11095934.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值