DFS分成互质组

大家点个赞吧,谢谢啦

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

至少要分成多少个组?

输入格式

第一行是一个正整数 n。

第二行是 n 个不大于10000的正整数。

输出格式

一个正整数,即最少需要的组数。

数据范围

1≤n≤10

输入样例:

6
14 20 33 117 143 175

输出样例

3

思路:

1.准备两个额外函数:

(1).求两个数之间的最大公约数

(2).判断当前组中的数是否和该数都互质

2.递归参数解释

dfs(g, gc, tc, start)

g :为当前的最后一组的组的序号.

gc: 为当前组内搜索到的数的序号;

tc:为当前搜索过的数的数量

     作用:便于判断组内分组是否结束

start:当前组开始搜索的数的序号

3.一些相关性变量解释

group[][] :存储每个组内的元素,便于判断是否互质

ans : 所有分组情况中最小的分组数

p[]:原数组,存放初始所有数

flag :用于判断该分组是否已经完成

st[] :标记该数是否已经被分进组里过

#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;
const int N = 15;
int p[N];
int group[N][N];
bool st[N];
int ans; 
int n;

//寻找最大公约数
int gcd(int a, int b)
{
    return b ? gcd(b, a%b) : a;
}

//判断该数和组内所有数是由都互质
bool check(int g[], int gc, int num)
{
    for(int i=0; i<gc; i++)
    {
        if(gcd(g[i], p[num]) > 1)
            return false;
    }
    return true;
}

void dfs(int g, int gc, int tc, int start)
{
    if(g >= ans) return ; //若此时分组数已经大于最优解,则没有必要再搜索下去
    if(tc == n) ans = g; //说明搜索完所i有点了,且分组方案数不大于最优解
                         //注意:最后一个点已经搜过了,因为从0开始计数
    bool flag = true; //标记是否能重新开一组
    for(int i = start; i < n; i ++)
    {
        if(!st[i] && check(group[g], gc, i))//满足的条件
        {
            group[g][gc] = p[i]; //放进组里,并标记
            st[i] = true;
            dfs(g, gc+1, tc+1, i+1);
            //回溯
            flag = false;
            st[i] = false;
        }
    }
    
    if(flag) dfs(g+1, 0, tc, 0);//没有元素再能进组,重开一组,
                                //并重新搜索元素
}

int main()
{
    cin >> n;
    ans = n;//此为分组的最坏情况
    for(int i=0; i<n; i++) cin >> p[i];
    
    dfs(1, 0, 0, 0);
    
    cout << ans;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值