首页 > 编程语言 >分成互质组 (dfs算法)

分成互质组 (dfs算法)

时间:2023-01-04 12:35:09浏览次数:41  
标签:return gcd int dfs 算法 ans 互质

Description

给定 n 个正整数,将它们分组,使得每组中任意两个数互质。

至少要分成多少个组?

Input

第一行是一个正整数 n ( 1 ≤ n ≤ 10 )。

第二行是 n 个不大于 10000 的正整数。

Output

一个正整数,即最少需要的组数

Sample Input

6
14 20 33 117 143 175

Sample Output

3

 

思路:利用dfs搜索所有符合题意(各组内两两互质)的情况,并更新组数最小值

代码(含注释):

#include<bits/stdc++.h>
using namespace std;
 
#define N 12
 
int arr[N];//存储所有数值
int se[N][N];//分组
int num[N];//记录各组存储数值的数量
int k = 0;//当前一共有k组
int n, ans = 100;
 
int gcd(int a, int b) {
    return b ? gcd(b, a % b) : a;
}
 
//分配第x个数值
void dfs(int x) {
    //当分配第n+1个数值时说明前n个数值全部分组完毕
    if (x == n + 1) { 
        ans = min(ans, k);
        return; 
    }
 
    //将当前第x个数值分配到当前各组中或者自身独立另开一组
    for (int i = 1; i <= k + 1; i++) {
        int j = 0;
 
        //判断第i组内各数值与arr[x]是否互质
        for (j = 0; j < num[i]; j++) {
            if (gcd(arr[x], se[i][j]) != 1)
                break;
        }
 
        //j==num[i]说明第i组中所有的数均与arr[x]互质
        if (j == num[i]) {
            if (j == 0) {//j==0说明arr[x]自身另开一组
                if (ans <= k + 1)//剪枝:如果新开一组大于当前最小值,则没有新开一组的必要
                    continue;
                else k++;
            }            
            se[i][num[i]++] = arr[x];
            dfs(x + 1);
            if (j == 0)k--;    //回溯
            num[i]--; //回溯
        }
 
    }
 
}
 
int main() {
 
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        scanf("%d", &arr[i]);
 
    //先将第一个数值分配到第一组中
    se[1][num[1]++] = arr[1];
    k = 1;
 
    //继而分配第二个数值
    dfs(2);
 
    printf("%d\n", ans);
 
    return 0;
    
}
View Code

代码(无注释):

#include<bits/stdc++.h>
using namespace std;
 
#define N 12
 
int arr[N];
int se[N][N];
int num[N];
int k = 0;
int n, ans = 100;
 
int gcd(int a, int b) {
    return b ? gcd(b, a % b) : a;
}
 
 
void dfs(int x) {
 
    if (x == n + 1) { 
        ans = min(ans, k);
        return; 
    }
 
    for (int i = 1; i <= k + 1; i++) {
        int j = 0;
        for (j = 0; j < num[i]; j++) {
            if (gcd(arr[x], se[i][j]) != 1)
                break;
        }
 
        if (j == num[i]) {
            if (j == 0) {
                if (ans <= k + 1)
                    continue;
                else k++;
            }            
            se[i][num[i]++] = arr[x];
            dfs(x + 1);
            if (j == 0)k--;
            num[i]--;
        }
 
    }
 
}
 
int main() {
 
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        scanf("%d", &arr[i]);
 
    se[1][num[1]++] = arr[1];
    k = 1;
 
    dfs(2);
 
    printf("%d\n", ans);
 
    return 0;
    
}
View Code

 

标签:return,gcd,int,dfs,算法,ans,互质
From: https://www.cnblogs.com/zcnsblog/p/17024494.html

相关文章