题目描述
给定 n 个正整数,将它们分组,使得每组中任意两个数互质。
至少要分成多少个组?
输入格式
第一行是一个正整数 n。
第二行是 n 个不大于10000的正整数。
输出格式
一个正整数,即最少需要的组数。
数据范围
1≤n≤10
输入样例:
6
14 20 33 117 143 175
输出样例:
3
算法dfs,按数枚举 时间复杂度O(?) 20ms
直接爆搜
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int N = 15;
int a[N],n,res=N;
vector<int> g[N];
int gcd(int a,int b)
{
return b==0?a:gcd(b,a%b);
}
bool check(int num,int x)
{
for(auto t:g[num])
{
if(gcd(t,x)>1)
return false;
}
return true;
}
void dfs(int u,int len)
{
if(len>=res) return ;
if(u==n)
{
res=len;
return;
}
for(int i=0;i<len;i++)
if(check(i,a[u]))
{
g[i].push_back(a[u]);
dfs(u+1,len);
g[i].pop_back();
}
g[len].push_back(a[u]);
dfs(u + 1,len+1);
g[len].pop_back();
}
int main(){
cin >> n;
for(int i=0;i<n;i++) cin >> a[i];
dfs(0,0);
cout << res << endl;
return 0;
}
大佬,我发现这个dfs这种分组问题有两种做法,第一种就是:枚举每个数要分到哪一组,这种的话没有等效冗余,第二种:枚举哪一组应该放进那些数,这种需要优化等效冗余,但是有的时候我不知道哪一种好。就比如这道题第一种做法20ms, 第二种600+ms, 但是在木棒那道题中y总就是用的第二种来优化各种剪枝,我试了第一种没办法用到第二种用到的剪枝(应该只能用第二种做法还是我太菜了没想到),不知道这两种做法到具体题目该如何抉择还是靠经验。求解。
爆搜题太玄学了,我也不是很内行,做这种题也比较少qwq
了解,谢谢。
这题第二种也可以优化的,枚举组间时按组合数枚举就可以了哦
大佬,您的代码交上去好像是错的。。。而且当前数能放进已有的互质组就不用开新的互质组我觉得这个结论也有点小问题。。
y总把数据增强了。。。这个结论按我这个枚举确实有点问题,感谢大佬指正