题面
题解
枚举组,开始将第一个数放入第一组,然后判断下一个数能否放到这个组,如果能就继续dfs下一个数,如果不能就新开一个组,从头开始扫描没有被放的数能否放到新的组
代码
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=11;
int n;
int p[N]; //输入的数
int group[N][N]; //组
bool st[N]; //是否被用过
int ans=N; //最大被分成N组
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
bool check(int group[],int gc,int i){
for(int j=0;j<gc;j++){
if(gcd(p[group[j]],p[i])>1){
return false;
}
}
return true;
}
//目前是第g个组,组内有gc个元素,搜到下标是start的元素,现在已经搜索了tc个数
void dfs(int g,int gc,int tc,int start){
if(g>ans) return; //剪枝
if(tc==n) ans=g; //搜完所有数更新答案
bool flag=true;
for(int i=start;i<n;i++){
if(!st[i]&&check(group[g],gc,i)){
st[i]=true;
group[g][gc]=i;
dfs(g,gc+1,tc+1,i+1);
st[i]=false;
flag=false;
}
}
if(flag) dfs(g+1,0,tc,0);
}
int main(){
cin>>n;
for(int i=0;i<n;i++) cin>>p[i];
dfs(1,0,0,0);
cout<<ans<<endl;
return 0;
}