Openjudge7834: 分成互质组
描述
给定n个正整数,将它们分组,使得每组中任意两个数互质。至少要分成多少个组?
输入
第一行是一个正整数n。1 <= n <= 10。
第二行是n个不大于10000的正整数。
输出
一个正整数,即最少需要的组数。
样例输入
6
14 20 33 117 143 175
样例输出
3
初想时真的毫无思路。。可能太菜了Orz
下面贴代码
#include <iostream>
using namespace std;
/* 分成互质组
* 思路:对于每个数,要么把它放到之前的组里,要么单独列成组,dfs解决
*/
int a[15], s[15], f[15][15], n, result = 0x7f; //a[15]为元素,s[15]为元素属于的集合
int gcd(int x, int y) //判断最大公约数
{
if (y == 0) return x;
else return gcd(y, x % y);
}
void DFS(int pos, int ans) //pos表示当前取到的位置,ans表示有多少个组
{
if (ans >= result) return; //剪枝
if (pos > n) { result = ans; return; }
for (int i = 1; i <= ans; i++) //枚举每个集合
{
bool flag = true;
for (int j = 1; j < pos; j++) //如果有a[pos]之前的数属于这个集合且不与a[pos]互质,这个集合不满足要求
{
if (s[j] == i && f[pos][j] != 1) { flag = false; break; }
}
if (flag) //否则,把a[pos]归到这个集合里,搜索下一层
{
s[pos] = i;
DFS(pos + 1, ans);
}
}
s[pos] = ans + 1; //或者,a[pos]单独再成立一个集合,搜索下一层
DFS(pos + 1, ans + 1);
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) f[i][j] = gcd(a[i], a[j]);
s[1] = 1;
DFS(2, 1);
cout << result;
return 0;
} `