AcWing 1118 分成互质组

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

至少要分成多少个组?

输入格式

第一行是一个正整数 n。

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

输出格式

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

数据范围

1≤n≤10

输入样例:

6
14 20 33 117 143 175

输出样例:

3

#include<bits/stdc++.h>
using namespace std;
const int N = 10;
int gcd(int x, int y) {//辗转相除法
    return y ? gcd(y, x % y) : x;
}
int n, a[N], ans = N, len;
vector<int> g[N];//g[i]表示第i个互质组
bool inline check(int u, int c) {
    for (int i = 0; i < g[c].size(); i++)//枚举这一组的所有数,判断是否与一组中的每一个数互质
        if(gcd(g[c][i], u) > 1) return false;
    return true;
}
void dfs(int u) {
    if(u == n) {//将所有的数分完了
        ans = min(ans, len);
        return;
    }
    for(int i = 0; i < len; i++) {//一共有0~len个互质组,每一个遍历过去
        if(check(a[u], i)) {//判断这个数是否能加入这个组
            g[i].push_back(a[u]);
            dfs(u + 1);
            g[i].pop_back();//深搜回溯
        }
    }
    /*
    注意如果这个数可以加入互质组,不能在push_back后马上return,因为即使这个数可以加入这个互质数组,也不能说明这是最优决策(新加入的数会影响后面)
    所以不管能不能,都要分为两种情况
    */
    g[len++].push_back(a[u]);//将这个数新加入一个互质组
    dfs(u + 1);
    g[--len].pop_back();//回溯
}
int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; i++) scanf("%d", a + i);
    dfs(0);
    printf("%d\n", ans);
}

posted @ 2022-09-24 21:16  zyc_xianyu  阅读(24)  评论(0编辑  收藏  举报