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);
}