多重集合的全排列

多重集合的定义:多重集合不要求元素不能重复。

多重集合表示

\(M=\left \{k_{1}\cdot a_{1},k_{2}\cdot a_{2},\cdots ,k_{n}\cdot a_{n}\right \}\)\(\left ( 其中每个a_{i}代表是不同的元素,每个元素a_{i}有k_{i}个,k_{i}可以是有限数,也可以是∞。\right )\)

多重集的排列:

  • \(多重集合M=\left \{k_{1}\cdot a_{1},k_{2}\cdot a_{2},\cdots ,k_{n}\cdot a_{n}\right \}的r排列数为k^{r}\)
  • \(多重集合M=\left \{k_{1}\cdot a_{1},k_{2}\cdot a_{2},\cdots ,k_{n}\cdot a_{n}\right \}的全排列数为:\frac{\left ( k_{1}+k_{2}+\cdots +k_{n}\right )!}{k_{1}!k_{2}!\cdots k_{n}!}\)

 例题:here

 

 题解:

\(n\)个数,选择\(n-1\)种,那么有\(C_{n}^{n-1}也就是n种\)方案。对于每种方案,要从\(n-1\)个数里面,选择一个重复的数字,有\(n-1\)种方案。此时对于每种方案,长度都是为\(n\)的序列,考虑多重集合的全排列方案数。根据公式可知全排列数为\(\frac{n!}{2!}\),所以题目答案就是:\(n\ast \left ( n-1\right )\ast \frac{n!}{2!}把除以2的阶乘转换为乘以2的阶乘的逆元\)

AC_Code:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 1e5+10;
 5 const ll mod=1e9+7;
 6 
 7 ll F[maxn];
 8 ll n;
 9 
10 void init(){
11     F[0]=F[1]=1;
12     for(int i=2;i<=100000;i++) F[i]=1ll*F[i-1]*i%mod;
13 }
14 
15 ll qpow(ll a,ll b){
16     ll res=1;
17     while(b){
18         if( b&1 ) res = res*a%mod;
19         a = a*a%mod;
20         b>>=1;
21     }
22     return res;
23 }
24 
25 int main()
26 {
27     init();
28     ll t2=qpow(2,mod-2);
29     while( ~scanf("%lld",&n)){
30         ll ans=n*(n-1)%mod*F[n]%mod*t2%mod;
31         printf("%lld\n",ans);
32     }
33     return 0;
34 }

 

posted @ 2020-07-16 09:24  swsyya  阅读(1382)  评论(0编辑  收藏  举报

回到顶部