文章目录

  • 92. 递归实现指数型枚举
  • 1572. 递归实现指数型枚举 II
    • 解法一:
    • 解法二:

周更打卡ACwing!可是感觉好难啊,要看好久才能懂,加油!

92. 递归实现指数型枚举


首先使用数组 x[i] 标记当前数i是否被选择过,x[i]=1表示被放入输出序列,x[i]=0则不被放入。当我们对所有的数进行了选择后(即current>n),根据x[i]就可以决定输出最终的序列。

那么从x[1]开始,尝试所有可能的组合,直观表示如下(此部分涉及dfs):

可以将过程进行拆解,每个数都有两种情况x[i]=1或者x[i]=1,在确定当前的数是否会被放入所选序列后,就要选择下一个应该被放入序列的数,所以执行dfs(current+1)。值得注意的是要确定递归结束的条件,也就是所选择的数达到最大限制n。所以得到如下代码:

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int x[20];//标记当前是否被选择过
int n;
void dfs(int current)
{if(current>n)//到达叶子结点输出结果{for(int i=1;i<=n;i++)if(x[i])cout<<i<<' ';cout<<endl;return ;}x[current]=1;dfs(current+1);x[current]=0;dfs(current+1);
}
int main()
{cin>>n;dfs(1);return 0;
}

输出:

3
1 2 3
1 2
1 3
1
2 3
2
3

1572. 递归实现指数型枚举 II


看似和上一个题目类似,实则不然,上一个题的前提是不重复的待选数字1~n,所以可以直接使用数字i表示待选数字,这里出现了重复的数字则需使用另外一个数组a来对待选数字进行存储。另一个问题是当两个待选数字相同时,第一个题的方法就不适用了,如果两个数相同则在上一题会被当做不同的数来处理使得答案重复,如下:

那么应该怎么办呢?

解法一:

先对输入进行排序使得重复的元素相邻,若进行选择时前后两元素相同(以a[1]=a[2]=2为例),需要保证第一次选择的是2是a[1],这样保证结果出现 2 2 时前一个是a[1]后一个是a[2],这样相同数字的相邻组合只会被选择一次。这种方法可以总结为一个规则:前后两数相同时:若上一个未被选则回退到上一步,使其标记为1后当前才可以被选;若上一个被选则当前才有可能被选。这么做就能保证了两数重复的顺序只出现了一次,见下图可发现该规律,那么如何实现呢?

前后两数相同时:若上一个未被选则回退到上一步,使其标记为1后当前才可以被选;若上一个被选则当前才有可能被选。这句话的前提是上一步未被选,所以应先使所有的数的x[i]=0(也就是都不选),这样才能从中找到回退的条件,再添加回退条件,再尝试将x[i]赋为1。

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int x[20],a[20];//标记当前是否被选择过
int n;
void dfs(int c)
{if(c > n)//到达叶子结点输出结果{for(int i=1; i<=n; i++)if(x[i])cout<<a[i]<<' ';cout<<endl;return ;}x[c]=0;dfs(c+1);if(c>1&&a[c - 1] == a[c]&&x[c-1]==0)return;x[c]=1;dfs(c + 1);
}
int main()
{cin>>n;for(int i=1; i<=n; i++)cin>>a[i];sort(a+1,a+n);dfs(1);return 0;
}
/*
输入:4
1 2 2 2
*/

输出:


2
2 2
2 2 2
1
1 2
1 2 2
1 2 2 2

解法二:

同理也是要控制两个相同数字的出现顺序,但是此处换个思路,上一题使用标记数组x[i]来判断上一个数字是否被选择。而此处无需标记数组,直接使用num储存我们最终选中的序列。那么我们可以把选择过程中的每一步来作为输出的结果。

可以使用用动态数组num存储不同长度、不同顺序的排列结果,所以每次dfs后都要进行一次输出,不必判断是否到达叶子结点,好处是动态数组是栈的存储结构不必考虑下标,同时值得注意的是该数组的起始位置i=0,与之前不同。

以输入数据1 2 2为例,对于最终排列的每一个位置(即num[i])来说都需要考虑每个数字(即a[i])是否被选择,所以使用for(int i = u; i < n; i++)来遍历数组a,两数字相同表示为a[i - 1] == a[i]i != u表示该数在与前一个数相同且不是出现重复序列的第一个,那么此时应该跳过后续对该种情况的分支选择。(即continue——跳过当前的for循环选择下一个数)。

代码过程的图示如下:

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const int N = 20;
int a[N];
vector<int> num;
int n;
void dfs(int u)
{for(int i = 0; i < num.size(); i++)cout << num[i] << " ";cout<<endl;for(int i = u; i < n; i++){if(i != u && a[i - 1] == a[i])continue;num.push_back(a[i]);dfs(i + 1);num.pop_back();//回溯}return;}
int main()
{cin>>n;for(int i=0; i<n; i++)cin>>a[i];sort(a,a+n);dfs(0);return 0;
}
/*
输入:3
1 2 2
*/

输出:


1
1 2
1 2 2
2
2 2

【ACwing】一、基础算法:1.1 递归枚举(指数型)相关推荐

  1. PAT甲级题目翻译+答案 AcWing(基础算法与数据结构)

    1029 Median (25 分) 题意 : median中位数 给两个升序的序列,要求它们两个合并后的中位数 思路 : 双指针 语法 : long int #include <iostrea ...

  2. 基础算法:Hanoi塔(递归)

    Hanoi塔 "递归算法离不开递推方程的求解." 这里Hanoi塔有三个柱子,A\B\C.上面放着五个盘子,要将A柱的盘子全部移到C柱上: 其中规则: 1.小圆盘必须在大圆盘上面. ...

  3. (ACWing yxc基础算法课笔记) 前缀和

    我们有一个长度为n的数组. 我们的前缀和就是把这个原数组中的若干个元素进行累加计算. 这里有个重要的点就是下标一定要从1开始. 我们第一个问题就是如何去求我们的si: 我们的前i项和的求法是前i-1项 ...

  4. AcWing提高算法课Level-3 第六章 基础算法

    AcWing提高算法课Level-3 第六章 基础算法 位运算 AcWing 90. 64位整数乘法761人打卡 递推与递归 AcWing 95. 费解的开关520人打卡 AcWing 97. 约数之 ...

  5. AcWing进阶算法课Level-4 第七章 基础算法

    AcWing进阶算法课Level-4 第七章 基础算法 启发式合并 AcWing 2154. 梦幻布丁73人打卡 AcWing 3189. Lomsat gelral54人打卡 manacher算法 ...

  6. AcWing基础算法课Level-2 第四讲 数学知识

    AcWing基础算法课Level-2 第四讲 数学知识 您将学会以下数学名词 质数,试除法,埃式筛法,线性筛,辗转相除,算术基本定理,质因数分解,欧拉函数,快速幂,费马小定理,逆元,拓展欧几里得,一次 ...

  7. AcWing基础算法课Level-2 第五讲 动态规划

    AcWing基础算法课Level-2 第五讲 动态规划 背包问题 AcWing 2. 01背包问题3018人打卡 AcWing 3. 完全背包问题2749人打卡 AcWing 4. 多重背包问题255 ...

  8. AcWing基础算法课Level-2 第二讲 数据结构

    AcWing基础算法课Level-2 第二讲 数据结构 单链表 AcWing 826. 单链表3453人打卡 双链表 AcWing 827. 双链表2865人打卡 栈 AcWing 828. 模拟栈3 ...

  9. AcWing基础算法课Level-2 第六讲 贪心

    AcWing基础算法课Level-2 第六讲 贪心 区间问题 AcWing 905. 区间选点1751人打卡 AcWing 908. 最大不相交区间数量1613人打卡 AcWing 906. 区间分组 ...

  10. AcWing 算法基础课第三节基础算法3 双指针、位运算、离散化、区间合并

    1.该系列为ACWing中算法基础课,已购买正版,课程作者为yxc 2.y总培训真的是业界良心,大家有时间可以报一下 3.为啥写在这儿,问就是oneNote的内存不够了QAQ ACwing C++ 算 ...

最新文章

  1. 蚁群用户界面:一群桌面运动的机器人
  2. SQL语句复习【专题八】
  3. android开发版本,Android开发之版本统一规范
  4. 【opencv】【mediapipe】手势检测的有趣玩法
  5. 数学公式识别:基于编码-解码模型
  6. [企业内部https证书配置]tomcat 7配置https的完整历程
  7. 赛门铁克第三财季运营业绩稳步增长
  8. mysql 5.7.15发布
  9. BZOJ 1304: [CQOI2009]叶子的染色
  10. 使用云服务器的几个安全防护技巧
  11. 「三代组装」使用Pilon对基因组进行polish
  12. web.xml.jsf_JSF 2.0 Ajax世界中的GMaps4JSF
  13. php 360全景,HTML5 Canvas实现360度全景方法
  14. 轻量级java框架 light-4j
  15. 上层应用程序是如何访问到底层驱动程序的呢?
  16. 微信小程序-如何引入地图组件及显示当前所在位置
  17. 人工智能的“虚假式繁荣”
  18. 在Unity中制作完整的技能系统(代码篇)
  19. 4G LTE 频率表
  20. 免费外链图片网站收集

热门文章

  1. mysql got signal 11_轻松解决MYSQL错误mysqld got signal 11 ;
  2. 流媒体技术学习笔记之(七)进阶教程OBS参数与清晰度流畅度的关系
  3. 物联网毕业设计 - 物联网毕设项目分享 有趣的毕设项目(单片机 嵌入式 物联网 stm32)
  4. 天猫运营和淘宝运营有哪些区别 天猫淘宝运营差异性
  5. mysql数据库安装过程蜿蜒曲折
  6. OpenAI公开Dota 2论文:胜率99.4%,「手术」工具连续迁移训练
  7. Fedora34/35/36 软件闪退解决
  8. vscode 设置关键字高亮显示
  9. 安装cygwin软件
  10. LeetCode 分割整数数组,分割为两部分的和相等