B21 DFS剪枝 分成互质组

视频链接:122 分成互质组 DFS剪枝_哔哩哔哩_bilibili

ybt1221 分成互质组

2

 

 

#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;

const int N=11;
int n,a[N],ans=N,cnt;
vector<int> g[N];

int gcd(int x,int y){
  return y?gcd(y,x%y):x;
}
bool check(int x,int i){
  for(int j=0; j<g[i].size(); j++)
    if(gcd(x,g[i][j])>1) return false;
  return true; 
}
void dfs(int u){
  if(cnt>=ans) return;       //剪枝
  if(u==n){ans=cnt; return;} //边界
  for(int i=0; i<cnt; i++)   //枚举已有组
    if(check(a[u],i)){ //如果a[u]能放第i组
      g[i].push_back(a[u]); //放入第i组
      dfs(u+1);
      g[i].pop_back();      //恢复现场
    }
  g[cnt++].push_back(a[u]); //新开一组
  dfs(u+1);
  g[--cnt].pop_back();      //恢复现场
}
int main(){
  scanf("%d",&n);
  for(int i=0; i<n; i++)scanf("%d",a+i);
  dfs(0);
  printf("%d\n",ans);
}

 

#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;

const int N=11;
int n,a[N],ans=N;
vector<int> g[N];

int gcd(int x,int y){
  return y?gcd(y,x%y):x;
}
bool check(int x,int i){
  for(int j=0; j<g[i].size(); j++)
    if(gcd(x,g[i][j])>1) return false;
  return true; 
}
void dfs(int u,int cnt){
  if(cnt>=ans) return;       //剪枝
  if(u==n){ans=cnt; return;} //边界
  for(int i=1; i<=cnt; i++)  //枚举已有组
    if(check(a[u],i)){ //如果a[u]能放第i组
      g[i].push_back(a[u]); //放入第i组
      dfs(u+1,cnt);
      g[i].pop_back();      //恢复现场
    }
  g[cnt+1].push_back(a[u]); //新开一组
  dfs(u+1,cnt+1);
  g[cnt+1].pop_back();      //恢复现场
}
int main(){
  scanf("%d",&n);
  for(int i=0; i<n; i++)scanf("%d",a+i);
  dfs(0,0);
  printf("%d\n",ans);
}

 

posted @ 2023-06-17 12:15  董晓  阅读(301)  评论(0编辑  收藏  举报