枚举算法
6.1 算法策略
枚举算法的思想是:将问题的所有可能的答案一一列举,然后根据条件判断此答案是否合适,保留合适的,丢弃不合适的。
枚举:即对可能的解集合一一列举。
枚举算法的实现往往通过使用循环(嵌套)就能够轻易实现,所以并没有什么思维难度。
6.2 解题思路
1. 对解的每个参数的数据范围采用循环语句一一枚举,对每次枚举采用if语句判断是否是解以及是否是最优解。
枚举小技巧:
1. 有时候,我们枚举的东西如果满足一个公式,我们的循环可以少写一层,优化效率。比如如果枚举A+B+C=100,我们只需要枚举A和B,C可以直接用100-A-B,这样就少一层循环。
2. 当然,改变枚举的顺序也是一种小技巧。一般都是从小到大或者从大到小,但是还有其他顺序,这就用到了贪心算法。
3. 有时候我们需要枚举的是每个东西的状态(一般为两种状态),我们可以用二进制里面的0/1来表示这两种状态来进行枚举。比如(二进制枚举)有5个小朋友,枚举他们是否看过该博客,这时候可以把看过或者没有看过表示两种状态,分别用0和1表示。现在给数字5,二进制是101,说明第1和第3个小朋友看过。所以我们可以枚举0~(31)来表示5个小朋友每个小朋友之间的状态是什么。
4. 有时候,我们枚举的故率达不到题目所需,我们就可以将枚举出来的所有结果事先保存下来,然后在第二份程序里直接调用,这就是打表的思想。
5. 还有时候,简单的循环嵌套可能满足不了我们的需求,可以考虑递归算法实观。
例题
给你 nn 根火柴棍,你可以拼出多少个形如 "A+B=C" 的等式?等式中的 A、B、C 是用火柴棍拼出的整数(若该数非零,则最高位不能是 0)。
用火柴棍拼数字 0-9,0−9 的拼法如图所示
注意:
加号与等号各自需要两根火柴棍
如果 A B,则A+B=C与B+A=C 视为不同的等式(A、B、C ≥0)
n 根火柴棍必须全部用上
输入格式
输入一个整数 n(n≤24)。
输出格式
输出能拼成的不同等式的数目。
代码 :
#include<iostream>
using namespace std;
int main()
{
int a[2001] = { 6 }, n, c[10] = { 6,2,5,5,4,5,6,3,7,6 }, s = 0, i, j;
//a数组表示下标所需要的火柴数,a[0]=6,其他的是0;n即输入的n的大小;其中c数组存储0~9数字所需要的火柴数
cin >> n;
for (i = 1; i <= 2000; i++)//因为1111是四位数用的最少的数,1111+1=1112此时就25根棍子了,所以基本上就不会实现四位数,但是把上界稍微放大了
{
j = i;
while (j >= 1)//将数字进行十进制的拆分,将i所需要的火柴数放入a数组中
{
a[i] = a[i] + c[j % 10];
j = j / 10;
}
}
for (i = 0; i <= 1000; i++)//求出该等式所需要的火柴棍
{
for (j = 0; j <= 1000; j++)
if (a[i] + a[j] + a[i + j] + 4 == n)//+4是因为+和=一共需要四根火柴棍
s++;//s表示符合要求的答案数
}
cout << s;
return 0;
}
枚举算法(Enumeration Algorithm)是一种基础的搜索算法,它通过遍历问题的所有可能情况来寻找解或进行计算。枚举算法通常适用于问题的解空间相对较小、可以通过遍历全部情况来解决的情况。
枚举算法的基本思想是通过穷举所有可能的解来找到满足条件的解。具体步骤如下:
1. 确定问题的解空间,即确定需要枚举的所有可能情况。
2. 选择一种遍历方式,逐个生成解空间中的元素。
3. 对每个生成的元素,判断是否满足问题的条件。
4. 如果满足条件,则找到一个解;如果不满足条件,则继续生成下一个元素。
5. 当所有的可能情况都遍历完后,得到的解即为问题的解。
枚举算法的优点是简单直观,能够找出问题的所有解。它适用于小规模问题或解空间相对较小的情况,且通常可以得到确切的结果。
然而,枚举算法的缺点是在解空间较大时,会遍历大量的情况,导致算法的时间复杂度较高,执行效率低下。因此,在使用枚举算法时,需要注意问题的规模和复杂度,选择合适的优化策略或其他算法来更高效地解决问题。
此外,有时候可以使用剪枝操作来减少遍历的情况数量,从而提高枚举算法的效率。对于某些问题,还可以结合其他技巧如双指针、二进制位运算等来优化枚举算法的实现。
需要注意的是,枚举算法不适用于求解某些特定类型的问题,如最短路径、最优解等,这些问题通常需要使用其他更复杂的算法来解决。在解决问题时,可以根据问题的特点和需求选择合适的算法。