[搜索] 质数-题解

时间:2024-10-15 19:53:17

由于 n n n 的范围很小,所以可以直接爆搜。
dfs(int x, vector<int> v, int l1, int l2) x x x 表示当前搜到的数的编号, v v v 表示当前的情况, l 1 l1 l1 表示 a n s 1 ans1 ans1 l 2 l2 l2 表示 a n s 2 ans2 ans2
如果 x > n x > n x>n,说明已经搜完了,更新答案。
否则继续搜索,接下来有两个情况:

  • 重新开一个新的组。
  • 在现在的组中,找到一个组使得每个数都与其互质,放进去。

接下来进行剪枝:

  1. 如果当前的已经比答案差了,直接返回。
  2. 还可以进行记忆化,如果搜到第 i i i 个数的答案已经不比前面搜到的更优,返回。

代码

int a[20];
bool check(int x, int y){//判断互质
	如果 gcd(x, y)1,则互质返回1,否则返回0
}
//组数,每组中最大元素个数
int ans1 = 1e9, ans2 = 1e9;
void dfs(int x, vector<int> v[20], int l1, int l2){
	if(l1 > ans1){
		return;
	}
	if(l1 == ans1 && l2 >= ans2){
		return;
	} 
	if(x > n){
		if(l1 < ans1){
			ans1 = l1;
			ans2 = l2;
		}
		else if(l1 == ans1){
			ans2 = min(ans2, l2); 
		}
		return;
	}
	vector<int> t[20];
	for(int i = 1; i <= l1; ++ i){
		for(auto j : v[i]){
			t[i].push_back(j);
		}
	}
	----新开一组----
	t[l1 + 1].push_back(a[x]);
	dfs(x + 1, t, l1 + 1, max(l2, 1));
	----从已有的组中选出组放进去----
	for(int i = 1; i <= l1; ++ i){
		int len = 0, fl = 1;
		for(auto j : v[i]){
			++ len;
			if(check(j, a[x]) == 0){
				fl = 0;
				break;
			}
		}
		//互质
		if(fl){
			vector<int> t1[20];
			for(int i1 = 1; i1 <= l1; ++ i1){
				for(auto j1 : v[i1]){
					t1[i1].push_back(j1);
				}
			}
			t1[i].push_back(a[x]);
			dfs(x + 1, t1, l1, max(l2, len + 1));
		}
	}
}
int main(){
	输入
	vector<int> v[20];
	dfs(1, v, 0, 0);
	输出
}