『ACM-算法-枚举法』信息竞赛进阶指南--枚举方法
你以为枚举是一个一个的找?
还真是
你以为枚举都是for循环?
还真是
但你真的会枚举吗?组合型枚举,指数型枚举,排列型枚举?难道你只会线形枚举?
你可太菜了!
// 递归实现指数型枚举
vector<int> chosen;
void calc(int x) {if (x == n + 1) {for (int i = 0; i < chosen.size(); i++)printf("%d ", chosen[i]);puts("");return;}calc(x + 1);chosen.push_back(x);calc(x + 1);chosen.pop_back();
}// 递归实现组合型枚举
vector<int> chosen;
void calc(int x) {if (chosen.size() > m || chosen.size() + (n - x + 1) < m) return;if (x == n + 1) {for (int i = 0; i < chosen.size(); i++)printf("%d ", chosen[i]);puts("");return;}calc(x + 1);chosen.push_back(x);calc(x + 1);chosen.pop_back();
}// 递归实现排列型枚举
int order[20];
bool chosen[20];
void calc(int k) {if (k == n + 1) {for (int i = 1; i <= n; i++)printf("%d ", order[i]);puts("");return;}for (int i = 1; i <= n; i++) {if (chosen[i]) continue;order[k] = i;chosen[i] = 1;calc(k + 1);chosen[i] = 0;order[k] = 0;}
}// 模拟机器实现,把组合型枚举改为非递归
vector<int> chosen;
int stack[100010], top = 0, address = 0;void call(int x, int ret_addr) { // 模拟计算机汇编指令callint old_top = top;stack[++top] = x; // 参数xstack[++top] = ret_addr; // 返回地址标号stack[++top] = old_top; // 在栈顶记录以前的top值
}int ret() { // 模拟计算机汇编指令retint ret_addr = stack[top - 1];top = stack[top]; // 恢复以前的top值return ret_addr;
}int main() {int n, m;cin >> n >> m;call(1, 0); // calc(1)while (top) {int x = stack[top - 2]; // 获取参数switch (address) {case 0:if (chosen.size() > m || chosen.size() + (n - x + 1) < m) {address = ret(); // returncontinue;}if (x == n + 1) {for (int i = 0; i < chosen.size(); i++)printf("%d ", chosen[i]);puts("");address = ret(); // returncontinue;}call(x + 1, 1); // 相当于calc(x + 1),返回后会从case 1继续执行address = 0;continue; // 回到while循环开头,相当于开始新的递归case 1:chosen.push_back(x);call(x + 1, 2); // 相当于calc(x + 1),返回后会从case 2继续执行address = 0;continue; // 回到while循环开头,相当于开始新的递归case 2:chosen.pop_back();address = ret(); // 相当于原calc函数结尾,执行return}}
}
『ACM-算法-枚举法』信息竞赛进阶指南--枚举方法相关推荐
- 『ACM-算法-Hash算法』信息竞赛进阶指南--字符串哈希
字符串hash主要应用在: 寻找长度为n的主串S中的匹配串T(长度为m)出现的位置或次数的问题属于字符串匹配问题. 类似的还有KMP,我也有讲解. 原理: 将字符串中的每一个字母都看做是一个数字(例: ...
- 『ACM--算法--KMP』信息竞赛进阶指南--KMP算法(模板)
简介: KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特-莫里斯-普拉特操作(简称KMP算法).KMP算法的核心是利用匹 ...
- 『ACM-算法-ST算法』信息竞赛进阶指南--区间最值问题的ST算法
借助倍增和动态规划可以实现O(1)的时间复杂度的查询 预处理: ①区间DP 转移方程 f[i][j] = min(MAX同理)(f[i][j - 1],f[i + ][j - 1]) f[i][j]表 ...
- 『ACM-算法-二分法』信息竞赛进阶指南--二分法
写在前面:我们主要还是分享算法的模板,而不是去刨析算法的原理! 定义: 二分答案是指在答案具有单调性的前提下,利用二分的思想枚举答案,将求解问题转化为验证结果. 流程: 首先需要估计答案的上下界,然后 ...
- 『ACM-算法-数据结构』信息竞赛进阶指南--树状数组 (模板)
写在前面: 我们是主要是讲算法模板,即实现的代码,并不讲实现的原理 什么是树状数组? 树状数组(Binary Indexed Tree(B.I.T), Fenwick Tree)是一个查询和修改复杂度 ...
- 『ACM-算法-离散化』信息竞赛进阶指南--离散化
数据离散化是一个非常重要的思想. 为什么要离散化? 当以权值为下标的时候,有时候值太大,存不下. 所以把要离散化的每一个数组里面的数映射到另一个值小一点的数组里面去. 打个比方,某个题目告诉你有104 ...
- 『ACM-数据结构』信息竞赛进阶指南--线段树
我们主要是讲代码实现,不是讲基本原理! 什么是线段树? 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 使用线段树可以快速的查找某一个节点 ...
- 『ACM--数据结构--字典树』信息竞赛进阶指南--Tire树
主要不是讲实现,是分享代码! 啥是字典树: Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎 ...
- 信息竞赛进阶指南--最小表示法
应用场景 一个首位相连的字符串,我们要寻找一个位置,从这个位置向后形成一个新字符串,我们需要使这个字符串字典序最小. 算法解释 我们这里要i = 0,j = 1,k = 0,表示从i开始k长度和从j开 ...
最新文章
- SDUT 1252 进制转换
- RESTful架构风格
- BundleFusion
- 【Linux网络编程】组播
- android mvp设计思想,Android-MVP设计模式(基础)
- 李宏毅 Gradient Descent总结
- 转载 游戏设计艺术中100个透镜
- 原生js实现音乐播放器功能,可以实时显示歌词并且高亮当前句
- MATLAB机器人工具箱的下载与安装
- Python学习日记之从Tushare上获取500成分股
- 关闭计算机后为什么重新启动,电脑关机后自动重启是怎么回事什么原因的解决方法 - 系统家园...
- 列车停车控制算法及仿真研究
- PMP-5.组织结构类型
- PureStake CEO Derek Yoo解释Moonbeam背后的技术
- 【云原生kubernetes】coredns解析集群外部域名
- day9:JAVA中while的用法
- 开关电源MOS管选型500V、600V、650V参数
- HTML实现一个简单的图片自动显示特效
- python实现输入一个正整数_Python中实现输入一个整数的案例
- 网页弹窗插件layer.js的使用
热门文章
- Windows下用命令行查找文件for命令的运用
- 服务器设备日常维护与管理论文,浅谈设备管理与维护论文
- 计算机网络 鲁士文,《在职研究生计算机网络课程统考复习指南》鲁士文 编_孔网...
- 安卓下载保存到本地(一)
- Android中保存数据的三种方法
- 1066. [SCOI2007]蜥蜴【最大流】
- html area图片热点
- C#Winform窗体实现服务端和客户端通信例子(TCP/IP)
- ARM Linux 如何--注册和触发--软中断
- linux系统安装锐捷客户端下载,Linux在宿舍里如何上网?--Fedora下锐捷802.1x客户端软件的安装和使用方法...