#include using namespace std; const int N = 20; const int INF = 0x3f3f3f3f; int n, a[N]; int ans = INF; vector 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; }