望山居

真相本来是一体的,太大了,所以大家给他画了格子,结果把自己困了起来

导航

排列组合的算法

排列组合算法

排列组合的数学基础

排列

\(n\) 个不同元素中, 每次取出 \(m(1≤m≤n)\) 个不同元素,排成一列,称为从 \(n\) 个元素中取出 \(m\) 个元素的无重复排列或直线排列,简称排列, 记作 \(P_n^m = \frac{n!}{(n-m)!}\);

组合

\(n\) 个不同元素中每次取出 \(m(0≤m≤n)\) 个不同元素,不管其顺序合成一组,称为从 \(n\) 个元素中不重复地选取 \(m\) 个元素的一个组合, 简称组合, 记作 \(C_n^m = \frac{n!}{m! \cdot (n-m)!}\)

全排列的递归算法描述

设一组元素 \(\Omega = \{A,B,C, \dotsb, N\}\);

\(n = 1\) 时: $Permutate(\Omega) = {A} $;

\(n = 2\) 时: \(Permutate(\Omega) = \{A, B\}, \{B, A\}\);

\(n = 3\) 时: \(Permutate(\Omega) = \{A, B, C\}, \{A, C, B\}, \{B, A, C\}, \{B, C, A\}, \{C, A, B\}, \{C, B, A\} \\ =A \{Permutate(\Omega - A)\} + B \{Permutate(\Omega - B)\} + C\{Permutate(\Omega - C)\}\);

...

对于 \(n\): 有 \(Permutate(\Omega) = \omega_1 \{Permutate(\Omega - \omega_1)\} +\omega_2 \{Permutate(\Omega - \omega_2)\} + \dotsb + \omega_n \{Permutate(\Omega - \omega_n)\}\)

template<class T>
void Recursion_Arrangament(int begin, int end, std::vector<T> dataSet)
{
	if (begin == end) // 终止条件
	{
		for (size_t i = 0; i < end; i++)
		{
			std::cout << dataSet[i];
		}
		std::cout << std::endl;
	}

	for (size_t i = begin; i < end; i++)
	{
		swap(dataSet[begin], dataSet[i]);
		Recursion_Arrangament(begin + 1, end, dataSet);
		swap(dataSet[i], dataSet[begin]);
	}
}

组合的递归算法描述

用 "10" 转换解决组合问题

在一组元素 \(\Omega = \{A,B,C, \dotsb, N\}\) 中选取 \(m\) 个作任意组合, \(Combine(N, m)\)

\(m = 3, n = 5\)

  1. 将元素数组的前三位标记为 1, 其余标记为 0;
  2. 从头读取标记为, 当遇到的第一组 10 时, 输出结果, 并转换 1001;
  3. 重复 步骤2, 直到队尾再没 10, 终止;
A B C D E Output
1 1 1 0 0 ABC
1 1 0 1 0 ABD
1 0 1 1 0 ACD
0 1 1 1 0 BCD
0 1 1 0 1 BCE
0 1 0 1 1 BDE
0 0 1 1 1 CDE

排列组合算法的地位

posted on 2022-08-30 14:20  穆道  阅读(470)  评论(0编辑  收藏  举报