题意:

给定 n 个正整数,将它们分组,使得每组中任意两个数互质。

问:至少要分成多少个组?

思路:

dfs,对每一个元素,我们有两种操作

  • ①:放到现有组中的最后一组中(依次枚举最后一组的所有元素,判断新加的元素是否与它们全部互质,如果是的则加入)
  • ②:新开一个组并放入

p[N]存放n个元素
二维数组group[N][N]存放每个组

我们从第一个组 g=1,组内没有数 gc=0,当前用掉了 cnt=0 个元素,当前组还未开始遍历数 start=0 的初始状态开始搜索。

每次搜索的时候判断是否可以将元素放到现有组中的最后一组(用标记变量ok),如果不行再新开一组。

空白代码:

#include<bits/stdc++.h>using namespace std;
const int N = 15;
int group[N][N], p[N];
bool st[N];
int n;
int ans;int gcd(int a, int b)
{return b ? gcd(b, a%b) : a;
}bool check(int g[], int gc, int a){for(int i=0;i<gc;++i){if(gcd(g[i], a)!=1) return false;}return true;
}void dfs(int g, int gc, int cnt, int start)
{if(g>=ans) return ;if(cnt==n) {ans = g; return ;}bool ok = false;for(int i=start; i<n; ++i){if(!st[i]&&check(group[g], gc, p[i])){st[i] = true;group[g][gc] = p[i];dfs(g, gc+1, cnt+1, i+1);st[i] = false;ok = true;}}if(!ok) dfs(g+1, 0, cnt, 0);
}int main()
{cin>>n;for(int i=0;i<n;++i) cin>>p[i];ans = n;dfs(1, 0, 0, 0);cout<<ans<<endl;return 0;
}

代码 + 注释:

#include<bits/stdc++.h>
using namespace std;const int N = 15;int n;
int p[N];//存放n个元素
int group[N][N];//存放每个组
bool st[N];
int ans;int gcd(int a, int b)
{return b ? gcd(b, a % b) : a;
}bool check(int g[], int gc, int a){//判断当前组中的数是否和该数都互质(即该数能否放进该组)for(int i=0;i<gc;++i)//枚举此组组内每个数{if(gcd(g[i], a)!=1) return false;//只要组内有数和该数不互质了就return false}return true;//否则return true
}void dfs(int g, int gc, int cnt, int start)
{//g为当前的最后一组的组的序号,gc为当前组内 搜索到的 数的序号//cnt为当前 搜索过的 元素数量,start为当前组 开始搜索的 数(p数组中的元素)的序号if (g >= ans) return;//如果有比当前最优解所需的组数更多的解法说明此解不为最优解-->直接return即可if (cnt == n) {ans = g; return ;}//如果搜完了所有点了,说明此解为当前的最优解,更新最优解bool ok = false;//flag标记是否能新开一组for (int i = start; i < n; ++i)//枚举每个数if (!st[i] && check(group[g], gc, p[i]))//如果当前数还未被放进组里 且 与当前的组中的数都互质{st[i] = true;group[g][gc] = p[i];//分支一:继续搜索该组,组内数的数量gc + 1,总的数的数量cnt + 1,搜索的数的序号i + 1(组合型枚举,人为规定一个递增的顺序)dfs(g, gc + 1, cnt + 1, i + 1);st[i] = false;ok = true;//如果能放进当前最后一组,则不用新开一组,ok标记为true}//分支二 经过for的枚举后发现无法放进最后一组,ok没有发生什么变化,还是false,则新开一组来搜索if (!ok) dfs(g + 1, 0, cnt, 0);//当前最后一组的组的序号g + 1, 组内搜索的数的序号gc为0//搜索到的数cnt未变, 当前组内开始搜索的数的序号start为0(仍重新从0开始搜,放不放入新开的组内就看是否满足条件了)
}int main()
{cin >> n;ans = n;//还未搜索时,假定最优解为最坏的情况每个数都分一组for (int i = 0; i < n; ++i) cin >> p[i];dfs(1, 0, 0, 0);//从第一个组 g=1, 组内没有数 gc=0//当前用掉了 cnt=0 个元素, 当前组还未开始遍历数 start=0 的初始状态开始搜索cout << ans << endl;return 0;
}

AcWing 1118. 分成互质组相关推荐

  1. 1118. 分成互质组

    给定 n 个正整数,将它们分组,使得每组中任意两个数互质. 至少要分成多少个组? 输入格式 第一行是一个正整数 n. 第二行是 n 个不大于10000的正整数. 输出格式 一个正整数,即最少需要的组数 ...

  2. 小学奥数 7834 分成互质组 python

    http://noi.openjudge.cn/math/7834/ 参考: 信息学奥赛一本通(1221:分成互质组) https://blog.csdn.net/lvcheng0309/articl ...

  3. 信息学奥赛一本通(1221:分成互质组)

    1221:分成互质组 时间限制: 1000 ms         内存限制: 65536 KB 提交数: 7405     通过数: 3453 [题目描述] 给定n个正整数,将它们分组,使得每组中任意 ...

  4. C++递归算法之分成互质组

    分成互质组 Description 给定n个正整数,将它们分组,使得每组中任意两个数互质.至少要分成多少个组? Input 第一行是一个正整数n.1 <= n <= 10. 第二行是n个不 ...

  5. POJ 7834:分成互质组

    " Ctrl AC!一起 AC!" 原题:忘题戳这 分析:对于一个数,遍历所有的互质组,如果可以进入一个组,并保持组内互质,则总组数不变.否则总组数加一. AC代码: #inclu ...

  6. 分成互质组 (信息学奥赛一本通-T1221)

    [题目描述] 给定n个正整数,将它们分组,使得每组中任意两个数互质.至少要分成多少个组? [输入] 第一行是一个正整数n.1 ≤ n ≤ 10. 第二行是n个不大于10000的正整数. [输出] 一个 ...

  7. 1221:分成互质组

    [题目描述] 给定n个正整数,将它们分组,使得每组中任意两个数互质.至少要分成多少个组? [输入] 第一行是一个正整数n.1 ≤ n ≤ 10. 第二行是n个不大于10000的正整数. [输出] 一个 ...

  8. 【noi 2.5_7834】分成互质组(dfs)

    有2种dfs的方法: 1.存下每个组的各个数和其质因数,每次对于新的一个数,与各组比对是否互质,再添加或不添加入该组. 2.不存质因数了,直接用gcd,更加快.P.S.然而我不知道为什么RE,若有好心 ...

  9. OpenJudge 7384(分成互质组)

    应hfu要求,近几日整理搜索专题的内容,无意中翻出了一年前死活A不掉的一道不可做题(当时觉得).看着自己的代码风格变化天翻地覆,无奈感叹时间飞逝...算了少矫情管他的先A了再说(ง •̀_•́)ง 先 ...

最新文章

  1. MATLAB 循环子字符串
  2. oracle实例是否有dbid,Oracle如何获得数据库的DBID
  3. oracle mysql 数据类型对比_Oracle、SQL Server、MySQL数据类型对比
  4. 项目经理的软技能提升——知行合一
  5. 设计模式13_享元模式
  6. 杭州师范大学计算机考研难度,杭州师范大学网络空间安全考研难吗
  7. 玩html5游戏用什么浏览器,玩HTML5游戏测浏览器傲游3最新版给力
  8. EXCEL VBA连接SQL数据库
  9. 第1篇:熊猫烧香之手动查杀
  10. 数电实验(二)利用8选1数据选择器74LS151设计四舍五入判别电路
  11. c语言编程学习入门指南
  12. 去除html中的font标签的正则表达式
  13. 《跑步人生》 作者:村上春树
  14. allt什么意思_all是什么意思_all怎么读_all翻译_用法_发音_词组_同反义词_全部的-新东方在线英语词典...
  15. 个人微信公众号申请流程
  16. Java生成ics文件
  17. 减半技术实现求a的n次幂
  18. 英语学习/词典app——top5
  19. Swiperjs插件轮播滑动卡顿优化
  20. Android中集成支付宝

热门文章

  1. C++实现超分辨率 IDN
  2. android加密技术框架,Android平台下文件透明加密技术的研究与实现
  3. python如何提高for循环效率_如何提高python的遍历效率?
  4. Ajax post sql注入,cmseasy前台无需登录直接获取敏感数据的SQL注入(有POC证明)
  5. 全志H616----火焰传感器
  6. HCIA总结DAY4
  7. 客户永恒不变的六大终极问题
  8. CSM与PMI-ACP的对比
  9. 一个srt字幕分割工具
  10. 送书|如果可以,我想给这本书打十星!