open judge 分成互质组 dfs 剪枝 求互质数 java

该文章是一个关于算法题解的Java程序,目标是将一组整数分成若干个互质的子集,每个子集中的所有数字最大公约数为1。程序使用深度优先搜索(DFS)策略,通过检查每组数字与当前集合是否互质来构建解决方案,并寻找最少的子集数量。
摘要由CSDN通过智能技术生成

🍑 算法题解专栏


🍑 open judge 分成互质组

在这里插入图片描述

输入

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值