c++枚举详解

枚举

什么是枚举

​ 枚举算法是我们在日常中使用最多的一种算法思想,它的核心思想是:枚举所有的可能,确定枚举对象、范围和判定条件;然后注意枚举可能的解并验证每个解是否是问题的解。

枚举的结构:

​ 循环+判断语句。

枚举算法的优点

  1. 枚举算法一般是现实生活问题的“直译”,所以比较直观,易于理解
  2. 枚举算法建立在考察大量状态、甚至是穷举所有状态的基础上,所有算法的真确性容易证明

枚举算法的缺点

​ 枚举算法的效率取决与枚举状态的数量和单个状态枚举的代价,所以枚举效率比较低

枚举的例题

例题1:数字统计

​ 请统计某个给定范围\([L,R]\)的所有整数中,数字2出现的次数
​ 比如给定范围[2, 22],数字 2 在数 2 中出现了 1 次,在数 12 中出现 1 次,在数 20 中出现 1 次,在数 21 中出现 1 次,在数 22 中出现 2 次,所以数字 2 在该范围内一共出现了 6次。
输入格式:
​ 输入共 1 行,为两个正整数 L 和 R,之间用一个空格隔开。
输出格式:
​ 输出共 1 行,表示数字 2 出现的次数。
输入样例 2 22 输出样例 6

思路:我们可以直接枚举范围\([L,R]\)中的每一个数,观察这个数中有几个数字\(2\)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl '\n'
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);

int n, m, res;

int main(){
	IOS
	cin >> n >> m;
	for(int i = n; i <= m; i++){
		int temp = i;
		while(temp){
			if(temp % 10 == 2) res++;
			temp /= 10;
		}
	}
	cout << res << endl;
	return 0;
} 

例题2:百钱白鸡

公鸡五元一只,母鸡三元一只,小鸡三只一元,现在你有一百元要买一百只鸡,问公鸡、母鸡、小鸡各多少买多少只。

思路,这题的数据范围很小,我们可以逐个枚举,一共买\(100\)只鸡,每种鸡买的范围为\([ 0,100 ]\)于是我们可以对三种鸡分别列举\(0\)\(100\)种可能.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl '\n'
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);

int res;

int main(){
	IOS
	for(int i = 0; i <= 100; i++){
		for(int j = 0; j <= 100; j++){
			for(int k = 0; k <= 100; k++){
				if(i + j + k == 100 && 15 * i + 9 * j + k == 300) 
					cout << i << " " << j << " " << k << endl;
			}
		}
	}
	return 0;
} 

​ 我们可以继续观察这个问题的代码,我们发现,这样的计算有很多多余的猜测,导致时间的消耗很大,为了减少多余的猜测,可以在已列举的情况下,不断排除空间内已不满足的解。由于公鸡是\(5\)元一只,所以公鸡最多可以买\(20\)只,同理母鸡最多可以买\(33\)只。又由于只买\(100\)只鸡,在枚举了前两种鸡的个数之后,第三只鸡的个数也已经得到了\(=100-i-j\)。因此我们就没有必要在进行枚举了。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl '\n'
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);

int res;

int main(){
	IOS
	for(int i = 0; i <= 20; i++){
		for(int j = 0; j <= 33; j++){
			int k = 100 - i - j;
			if(15 * i + 9 * j + k == 300)
				cout << i << " " << j << " " << k << endl;
		}
	}
	return 0;
} 

枚举算法的优化

  1. 枚举算法的时间复杂度:状态总数 \(\times\)单个状态的耗时
  2. 主要优化方法:
    减少状态总数
    降低单个状态的考察代价
  3. 优化过程从以下几个方面考虑:
    枚举对象的选取
    枚举方法的确定
    采用局部枚举或引进其他算法
posted @ 2021-04-20 00:46  h星宇  阅读(1028)  评论(0编辑  收藏  举报