DFS求分配互质数组组数

分配互质组

1.题目
输入N,和N个整数,求将这N个整数分成两两互质的组所需的组数。
(写个短题偷懒~)
在这里插入图片描述

2.思考:
两个数之间最大公约数为1即为互质。
那么,将数字当成节点,关系当成连接两个节点之间的边,将问题抽象成图。即如果两个数互质,那么对应两个节点有边相连。所以,按照顺序用dfs策略,判断考虑每一个数应该放到哪个组,可进入哪个组,相当于判断哪些节点相连,可走哪条路。

在这里插入图片描述

比如:设定组1为{2},组2为{3},那么数字4有三种选择,进入组1,进入组2,或者新建组3。则随机选择,进入组1发现组1数字2和数字4不互质,所以不可行,返。进入组2发现可行。则继续判断下一个数。
直到所有的数字都已经分配完毕则结束。

3.代码实现

#include<bits/stdc++.h>
using namespace std;

const int N=15;
int n;//元素个数 
int g[N];//存放题目所给出元素 
int ans=0x3f; //最终答案,初始化答案为一个大数 
int num=0;//目前组数
vector<int>v[N];//存放每一组的元素 
void dfs(int x);

bool check(int val,int k){//检验val能否放入第k组 
    for(int i=0;i<v[k].size();i++){
		if(__gcd(val,v[k][i])!=1)//__gcd(x,y)内置函数,返回x和y的最大公约数。如果最大公约数不为1,则互质 
            return false;
    }
    return true;
}

int main(){
    cin>>n;//输入数据 
    for(int i=1;i<=n;i++)
		cin>>g[i];
		
    dfs(1);//从第一个数开始搜索 
    cout<<ans<<endl;//输出结果 
	return 0;
}

void dfs(int x){
    if(x==n+1){//个数等于n+,即已经搜索完了最后一个数,遍历完毕 
        ans=min(num,ans);//更新组数得到答案 
        return;
	}
	
    int y=g[x];//获得x位置的值
    for(int i=1;i<=num;i++){
		if(check(y,i)){//判断是y否可以放入
         	v[i].push_back(y);  //将y放入相应组i 
            dfs(x+1);//继续搜索 
            v[i].pop_back();//将数y丢出来,恢复现场
		}
    }
    num++;//如果都不能放入,则新开一个数组 
    v[num].push_back(y);//放入y 
    dfs(x+1);
    v[num].pop_back();//恢复现场
    num--;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值