题解 信息学奥赛一本通/AcWing 1118 分成互质组 DFS C++

题目

传送门

AcWing

1118. 分成互质组 - AcWing题库https://www.acwing.com/problem/content/1120/https://www.acwing.com/problem/content/1120/https://www.acwing.com/problem/content/1120/https://www.acwing.com/problem/content/1120/https://www.acwing.com/problem/content/1120/信息学奥赛一本通

信息学奥赛一本通(C++版)在线评测系统https://ybt.ssoier.cn/problem_show.php?pid=1221https://ybt.ssoier.cn/problem_show.php?pid=1221https://ybt.ssoier.cn/problem_show.php?pid=1221https://ybt.ssoier.cn/problem_show.php?pid=1221https://ybt.ssoier.cn/problem_show.php?pid=1221

思路

怎么实现互质判断

互质的两个数,它们的最大公约数 (GCD) 为 1

不懂的话自己搜 "欧几里得算法/辗转相除法/求最大公约数"

模板代码

int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }

 怎么判断一个数能否加入某个分组

有一种做法是分组不存各个数,而是存它们的乘积

如,判断 7 是否能加入 2,3,5,只要判断 7 与 2*3*5 = 30 是否互质

分组里存 2*3*5 = 30 就行了

但是这种做法局限性高,分组内数的乘积比较小才行,不然会爆整型

所以还是老老实实存各个数。判断一个数是否能加入某个分组,要遍历判断互质关系

为什么要搜索,贪心不可以做吗?

贪心还真不行,不妨试试

贪心思路:能入则入:如果一个数能放进已有的分组,就放进去,而不是新建分组

这样的贪心思路确实能过样例数据,但是不能过所有数据,如:n{ 4 }, arr{ 3,7,6,14 }

若 "能入则入",则 3 >> 分组1,7 >> 分组1,6 >> 分组2,14 >> 分组3,这样要分 3 组

但这不是最优解,最优解是分 2 组:{ 3,14 }, { 7,6 }

通过这个数据我们不难发现,一个数放入一个分组,会影响后续的数放入这个分组

"能入则入" 可能会错过最优解,就像 7 和 3 放在一组,影响了 6 放入这个分组,错过了最优解

所以我们要搜索所有情况,对于当前的数,有如下分支

(1) 进入已有分组 0    (2) 进入已有分组 1    ......    (m) 另起一个分组,每种每支都要尝试枚举

DFS 问题,有思路但是写不出来可以画搜索树

代码

#include <vector>
#include <iostream>
using namespace std;
const int N = 12;
int n, num[N], ans;
vector<int> g[N];
int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
bool check(int G, int x) //遍历判断互质
{for (auto y : g[G])if (gcd(num[x], y) != 1)return false;return true;
}
void DFS(int x, int cnt) //cnt 表示当前分组的数量,cnt-1 表示最后一个分组的下标。如果要新建分组,cnt 表示新建分组的下标
{if (cnt >= ans) return; //最优性剪枝if (x == n) { ans = cnt; return; } //最优性剪枝保证了 cnt < ans,可以直接更新而不用 ans = min(ans, cnt)for (int i = 0; i < cnt; i++){if (check(i, x)) //可行性剪枝{g[i].push_back(num[x]); //处理现场DFS(x + 1, cnt);g[i].pop_back(); //恢复现场}}g[cnt].push_back(num[x]); //新建分组DFS(x + 1, cnt + 1); //新建分组g[cnt].pop_back(); //恢复现场
}
int main()
{cin >> n;for (int i = 0; i < n; i++) cin >> num[i];DFS(0, 0);cout << ans;return 0;
}

细节

分组用 vector 数组存,比用二维数组存省事儿得多。对自己好点,别没事儿折磨自己......

关于排列式搜索和组合式搜索

排列式搜索考虑顺序,一般通过多层嵌套实现,每层枚举范围为 [1, n]

通过标记数组避免重复选择。比较经典的题目有:递归实现排列型枚举

我以前还写过这个题的题解。。。

递归实现指数型、组合型、排列型枚举,按字典序输出-CSDN博客https://blog.csdn.net/qwq_ovo_pwp/article/details/141332402?spm=1001.2014.3001.5501https://blog.csdn.net/qwq_ovo_pwp/article/details/141332402?spm=1001.2014.3001.5501https://blog.csdn.net/qwq_ovo_pwp/article/details/141332402?spm=1001.2014.3001.5501https://blog.csdn.net/qwq_ovo_pwp/article/details/141332402?spm=1001.2014.3001.5501https://blog.csdn.net/qwq_ovo_pwp/article/details/141332402?spm=1001.2014.3001.5501当时刚学完C语言,初学算法没几天,比较菜

所以文章和代码写得不是很好,这个代码还能精简改善掉许多 (懒得再改了,凑合看吧)

组合式搜索不考虑顺序,一般通过多层嵌套实现,每层枚举范围不大于上层

即上层枚举 [i, n] 时该层枚举 (i, n] (左边可能是闭区间)

有时内层直接枚举外层的下一个,本题就是这样的 (DFS(x+1, ...))

在不考虑顺序时,排列型搜索的效率远低于组合型搜索

会重复搜索很多状态。本题搜索无顺序要求,故采用组合式搜索

就本题来说,这么搜索 (DFS(x+1, ...)) 为何能不重不漏地搜到所有情况

不理解的话画搜索树吧。可以发现对于每个数,每种分组情况都被枚举到了

满足条件时可以分到已有的任何分组或新建分组

任何分组都可能独立出一个分组,枚举到了所有分组都自成一组的情况

满足条件时也可以枚举到所有数都在一个分组的情况

参考文献 (雾)

AcWing 165. 小猫爬山 - AcWinghttps://www.acwing.com/activity/content/code/content/136433/https://www.acwing.com/activity/content/code/content/136433/https://www.acwing.com/activity/content/code/content/136433/https://www.acwing.com/activity/content/code/content/136433/https://www.acwing.com/activity/content/code/content/136433/只是参考了 y总 的注释和部分细节

(变量的初始值、具体含义等。我原先的版本 cnt 具体含义和此版本略有不同,初始值为 -1)

(不得不说这两个题目相似程度没有 100% 也有 10000% 了)

信息学奥赛一本通(1221:分成互质组) - 代码先锋网信息学奥赛一本通(1221:分成互质组),代码先锋网,一个为软件开发程序员提供代码片段和技术文章聚合的网站。https://www.codeleading.com/article/24965750320/https://www.codeleading.com/article/24965750320/https://www.codeleading.com/article/24965750320/https://www.codeleading.com/article/24965750320/https://www.codeleading.com/article/24965750320/"为什么要搜索,贪心不可以做吗?" 灵感来自这篇文章

"这道题没有必要放到dfs中,直接枚举即可" 我一开始也是这么想的

直到看到这篇文章并交了一发。。。。。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/8684.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

论文阅读笔记:VMamba: Visual State Space Model

论文阅读笔记&#xff1a;VMamba: Visual State Space Model 1 背景2 创新点3 方法4 模块4.1 2D选择性扫描模块&#xff08;SS2D&#xff09;4.2 加速VMamba 5 效果5.1 和SOTA方法对比5.2 SS2D和自注意力5.3 有效感受野5.4 扫描模式 论文&#xff1a;https://arxiv.org/pdf/240…

技术总结:FPGA基于GTX+RIFFA架构实现多功能SDI视频转PCIE采集卡设计方案

目录 1、前言工程概述免责声明 3、详细设计方案设计框图SDI 输入设备Gv8601a 均衡器GTX 解串与串化SMPTE SD/HD/3G SDI IP核BT1120转RGBFDMA图像缓存RIFFA用户数据控制RIFFA架构详解Xilinx 7 Series Integrated Block for PCI ExpressRIFFA驱动及其安装QT上位机HDMI输出RGB转BT…

03:Heap代码的分析

Heap代码的分析 1、内存对齐2、Heap_1.c文件代码分析3、Heap_2.c文件代码分析4、Heap_4.c文件代码分析5、Heap_5.c文件代码分析 1、内存对齐 内存对齐的作用是为了CPU更快的读取数据。对齐存储与不对齐存储的情况如下&#xff1a; 计算机读取内存中的数据时是一组一组的读取的…

自动驾驶---苏箐对智驾产品的思考

1 前言 对于更高级别的自动驾驶&#xff0c;很多人都有不同的思考&#xff0c;方案也好&#xff0c;产品也罢。最近在圈内一位知名的自动驾驶专家苏箐发表了他自己对于自动驾驶未来的思考。 苏箐是地平线的副总裁兼首席架构师&#xff0c;同时也是高阶智能驾驶解决方案SuperDri…

Android BitmapShader简洁实现马赛克/高斯模糊(毛玻璃),Kotlin(三)

Android BitmapShader简洁实现马赛克/高斯模糊&#xff08;毛玻璃&#xff09;&#xff0c;Kotlin&#xff08;三&#xff09; 发现&#xff0c;如果把&#xff08;二&#xff09; Android BitmapShader简洁实现马赛克&#xff0c;Kotlin&#xff08;二&#xff09;-CSDN博客 …

【数据结构】 并查集 + 路径压缩与按秩合并 python

目录 前言模板朴素实现路径压缩按秩合并按树高为秩按节点数为秩 总结 前言 并查集的基本实现通常使用森林来表示不同的集合&#xff0c;每个集合用一棵树表示&#xff0c;树的每个节点有一个指向其父节点的指针。 如果一个节点是它自己的父节点&#xff0c;那么它就是该集合的代…

【深度学习入门_机器学习理论】K近邻法(KNN)

本部分主要为机器学习理论入门_K近邻法(KNN)&#xff0c;书籍参考 “ 统计学习方法&#xff08;第二版&#xff09;”。 学习目标&#xff1a; 了解k近邻算法的基本概念、原理、应用&#xff1b;熟悉k近邻算法重要影响要素&#xff1b;熟悉kd树原理与优化应用。 开始本算法之…

深入理解 SQL 中的子查询

文章目录 一、什么是子查询二、子查询的基本语法三、数据准备四、子查询的分类4.1 标量子查询4.2 单行子查询4.3 多行子查询4.4 关联子查询 五、子查询的应用场景5.1 子查询与 WHERE 子句5.2 子查询与 SELECT 子句5.3 子查询与 FROM 子句 六、性能优化与注意事项 本文将深入探讨…

Zookeeper入门部署(单点与集群)

本篇文章基于docker方式部署zookeeper集群&#xff0c;请先安装docker 目录 1. docker初期准备 2.启动zookeeper 2.1 单点部署 2.2 集群部署 3. Linux脚本实现快速切换启动关闭 1. docker初期准备 拉取zookeeper镜像 docker pull zookeeper:3.5.6 如果拉取时间过长&#xf…

【SpringBoot教程】Spring Boot + MySQL + HikariCP 连接池整合教程

&#x1f64b;大家好&#xff01;我是毛毛张! &#x1f308;个人首页&#xff1a; 神马都会亿点点的毛毛张 在前面一篇文章中毛毛张介绍了SpringBoot中数据源与数据库连接池相关概念&#xff0c;今天毛毛张要分享的是关于SpringBoot整合HicariCP连接池相关知识点以及底层源码…

SCRM在企业私域流量与客户管理中的变革之路探索

内容概要 在当今数字化高速发展的时代&#xff0c;SCRM&#xff08;社交客户关系管理&#xff09;作为一种新的管理工具&#xff0c;正逐渐成为企业私域流量管理和客户关系维护的重要基石。它不仅仅是一种软件工具&#xff0c;更是一种整合客户数据和关系管理的全新思维方式。…

实战 | 域环境下通过anydesk进入生产网

视频教程在我主页简介或专栏里 目录&#xff1a; 前言 外网突破 资产扫描与常规漏洞 经典的MS17010漏洞利用&#xff1a; 网络通信设备弱口令&#xff1a; 安全防护设备集群&#xff1a; 域环境渗透 核心生产网渗透 总结 教程下载链接&#xff1a;zkanzz 话不多说&#x…

卡特兰数学习

1&#xff0c;概念 卡特兰数&#xff08;英语&#xff1a;Catalan number&#xff09;&#xff0c;又称卡塔兰数&#xff0c;明安图数。是组合数学中一种常出现于各种计数问题中的数列。它在不同的计数问题中频繁出现。 2&#xff0c;公式 卡特兰数的递推公式为&#xff1a;f(…

算法刷题Day28:BM66 最长公共子串

题目链接&#xff0c;点击跳转 题目描述&#xff1a; 解题思路&#xff1a; 方法一&#xff1a;暴力枚举 遍历str1的每个字符x&#xff0c;并在str2中寻找以相同元素x为起始的最长字符串。记录最长的公共子串及其长度。 代码实现&#xff1a; def LCS(self, str1: str, st…

Open FPV VTX开源之ardupilot双OSD配置摄像头

Open FPV VTX开源之ardupilot双OSD配置 1 源由2. 分析3. 配置4. 解决办法5. 参考资料 1 源由 鉴于笔者这台Mark4 Copter已经具备一定的历史&#xff0c;目前机载了两个FPV摄像头&#xff1a; 模拟摄像头数字摄像头(OpenIPC) 测试场景&#xff1a; 从稳定性的角度&#xff1…

【Super Tilemap Editor使用详解】(十六):高级主题:深入理解 Super Tilemap Editor

在本节中,我们将深入探讨 Super Tilemap Editor 的工作原理,特别是图块地图(Tilemap)的渲染机制以及如何优化性能。这些知识将帮助你更好地理解工具的内部机制,并在开发中做出更明智的决策。 一、图块地图与图块渲染 图块地图是 Super Tilemap Editor 的核心组件之一。它由…

01学习预热篇(D6_正式踏入JVM深入学习前的铺垫)

目录 学习前言 一、虚拟机的结构 1. Java虚拟机参数设置 2. java 堆 3. 出入栈 4. 局部变量表 1> 局部变量的剖析 2> 局部变量的回收 5. 操作数栈 1> 常量入栈指令 2> 局部变量值转载到栈中指令 3> 将栈顶值保存到局部变量中指令 6. 帧数据区 7. 栈…

Node.js下载安装及环境配置教程 (详细版)

Node.js&#xff1a;是一个基于 Chrome V8 引擎的 JavaScript 运行时&#xff0c;用于构建可扩展的网络应用程序。Node.js 使用事件驱动、非阻塞 I/O 模型&#xff0c;使其非常适合构建实时应用程序。 Node.js 提供了一种轻量、高效、可扩展的方式来构建网络应用程序&#xff0…

SimpleFOC STM32教程10|基于STM32F103+CubeMX,速度闭环控制(有电流环)

导言 SimpleFOC STM32教程09&#xff5c;基于STM32F103CubeMX&#xff0c;ADC采样相电流 如上图所示, 增加了电流环. 效果如下&#xff1a; 20250123-200906 RTT 如上图所示&#xff0c;三相占空比依然是马鞍波。当我用手去给电机施加阻力时&#xff0c;PID要维持目标转速&am…