🍑 算法题解专栏
输入
6
14 20 33 117 143 175
输出
3
🍤 最大公约数为 1 的两个数互质
import java.util.*;
public class Main
{
static int N = 15, n;
static ArrayList[] g = new ArrayList[N];
static int[] nums = new int[N];
static int ans = N;
// 最大公约数 间接求解 互质(最大公约数为 1 的两个数互质)
static int gcd(int a, int b)
{
return b == 0 ? a : gcd(b, a % b);
}
static boolean check(ArrayList<Integer> list, int x)
{
for (int i = 0; i < list.size(); i++)//枚举组内的每一个元素
if (gcd(list.get(i), x) > 1)//判断是否互质
return false;
return true;
}
// u 是当前处理数的nums数组下标,used是已经开了的组数
static void dfs(int u, int used)
{
// 剪枝:如果当前使用的组已经>=目前获得的最优解,停止当前分支的搜索
if (used + 1 >= ans)
return;
if (u >= n)
{
ans = Math.min(ans, used + 1);
return;
}
// 先在已经开的组里面找,看看能不能插进去
for (int i = 0; i <= used; i++)
{
if (check(g[i], nums[u]))// 可以加入此组
{
g[i].add(nums[u]);// 加入
dfs(u + 1, used);// 递归搜索
g[i].remove(g[i].indexOf(nums[u]));// 恢复现场
}
}
if (used + 1 <= n)// 为当前数新开一个组的情况
{
g[used + 1].add(nums[u]);// 加入
dfs(u + 1, used + 1);// 递归搜索
g[used + 1].remove(g[used + 1].indexOf(nums[u]));// 恢复现场
}
}
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
for (int i = 0; i < n; i++)
nums[i] = sc.nextInt();
for (int i = 0; i < n; i++)
g[i] = new ArrayList<Integer>();
dfs(0, 0);
System.out.println(ans);
}
}