基本公式
[A_n^m=frac{n!}{(n-m)!}
]
[C_n^m=frac{A_n^m}{m!}=frac{n!}{(n-m)!m!}
]
[C_n^m=C_n^{n-m}
]
[C_n^m=C_{n-1}^m+C_{n-1}^{m-1}
]
特殊排列组合
- 不同物品可重复选择m个物品:(C_{n+m-1}^m)
- 有k个不同的不同物品集,物品总数是n,物品集内的物品都完全相同,每个物品集的数量是(n_1,n_2,cdots,n_k),则这n个物品的排列数为$$n!/n_1!/n_2!/n_3!/cdots/n_k!$$
- n个有标号(1,2,3,cdots,n)的顶点的树的数目是(n^{n-2})
- 圆周排列
(Q(N,R))代表N中选R个的圆周排列
$$Q(N,R)=A(N,R)/R$$
$$Q(N,N)=(N-1)!$$
生成排列(允许可重集)
void dfs(int step){
if(step == n){
for(int i=1; i<n; i++) cout<<a[i]<<' ';
cout<<a[n]<<endl;
return;
}
for(int i=1; i<=n; i++)
if(book[i]<=2) //这里表示重复的数最多可以有两个
{
a[step+1]=i;
book[i]++;
dfs(step+1);
book[i]--;
}
}
生成组合
二进制法
for(int i=0;i<=(1<<n)-1;i++){
for(int j=0;j<n;j++){
if(i&(1<<j)) cout<<a[j]<<" ";
}
cout<<endl;
}