acwing 1118分成互质数(DFS搜索顺序)

题面

acwing 1118分成互质数(DFS搜索顺序)

题解

枚举组,开始将第一个数放入第一组,然后判断下一个数能否放到这个组,如果能就继续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;
}
上一篇:【PAT刷题甲级】1107.Social Clusters & 1118.Birds in Forest


下一篇:信息学奥赛一本通 1118:铺地毯 视频题解