You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

57 lines
1.6 KiB

2 years ago
#include <bits/stdc++.h>
using namespace std;
const int N = 20;
const int INF = 0x3f3f3f3f;
int n, a[N];
int ans = INF;
vector<int> g[N]; // 共几个组,每组都放哪些互质的数字
// 最大公约数,辗转相除法
int gcd(int a, int b) {
if (b == 0) return a;
return gcd(b, a % b);
}
// 枚举c组中每一个数字判断是否与u互质
int check(int u, int c) {
for (int i = 0; i < g[c].size(); i++)
if (gcd(g[c][i], u) > 1) return 0;
return 1;
}
void dfs(int u, int len) {
// 剪枝剪完后19ms,不剪36ms
if (len >= ans) return;
// 枚举完所有数字,结束
if (u == n + 1) {
ans = len; // 更新组数最小值,大的等的都被上面的那句剪枝给整回去了
return;
}
for (int i = 0; i < len; i++) { // 枚举前面所有的组
if (check(a[u], i)) { // 如果a[u]可以放入i组
g[i].push_back(a[u]); // 放进i组
dfs(u + 1, len); // 走到下一个数字面前,没有增加组数
g[i].pop_back(); // 回溯不入进i组
}
}
// 新开一组
g[len].push_back(a[u]); // 将a[u]这个数字放入到len这一组中
dfs(u + 1, len + 1); // 走到下一个数字面前现在的组数加了1个
g[len].pop_back(); // 回溯不放入len这一组中 
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
// 第1个数开始,现在0组
dfs(1, 0);
// 输出最少组数
cout << ans << endl;
return 0;
}