DFS之搜索顺序 AcWing 1118. 分成互质组

DFS之搜索顺序 AcWing 1118. 分成互质组

原题链接

AcWing 1118. 分成互质组

算法标签

DFS

思路

1 数组划分

划分策略
优先选择将该数加至最后一组,若无法将该数加至最后-组,新开数组并将该数放置新开数组中

在这里插入图片描述
证明
在这里插入图片描述

代码

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define int long long
#define x first
#define y second
#define ump unordered_map
#define pq priority_queue
#define rep(i, a, b) for(int i=a;i<b;++i)
#define Rep(i, a, b) for(int i=a;i>b;--i)
using namespace std;
typedef pair<int, int> PII;
const int N = 10;
//int t, n, m, cnt, ans; 
int n;
int p[N];
int group[N][N];
bool st[N];
//由于是求最小值,这里初始化为最大值
int ans=N;
inline int rd(){
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
   return s*w;
}
void put(int x) {
    if(x<0) putchar('-'),x=-x;
    if(x>=10) put(x/10);
    putchar(x%10^48);
}
// 判断下标为i的元素与数组g中元素是否互质
bool check(int g[], int gc, int i){
    rep(j, 0, gc){
        if(__gcd(p[g[j]], p[i])>1){
            return false;
        }
    }
    return true;
}
//当前需放置至哪个分组;要放在该分组的位置下标;当前已分组完毕的元素个数;从哪个位置开始选择元素【组合套路(定一个遍历顺序)】
void dfs(int g, int gc, int tc, int sta){
    // 当前搜素组数 > 当前答案 则当前答案非最终答案 直接返回
    if(g>=ans){
        return;
    }
    // 已将所有元素分到互斥的组中 更新答案
    if(tc==n){
        ans=g;
    }
    //从start开始找,是否有元素不能放到g组中
    bool flag=true;
    rep(i, sta, n){
    	// 尚未搜素过且与当前组内元素互质
        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;
        }
    }
    //新开一个分组
    //由于dfs每层之间确定了顺序,所以期间存在元素被漏掉,【比如一开始你找的一串序列(1)是1,2,3,4 但是第二次(2)是1,2,4 很显然此时
    //(2)还有一个3没有得到分组,需要从start=0开始把它找到!】
    //因此当所有元素都不能放进当前分组的时候 或者 当start=n-1了但是元素没有全部分组完毕时,要重新从start=0开始找,并且一定要有st数组!!!不然会把一个元素重复的分组!(即恢复现场)
    if(flag){
        dfs(g+1, 0, tc, 0);
    }
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	n=rd();
	rep(i, 0, n){
	    p[i]=rd();
	}
	//通过g就得到当前分组数;由于ans初始化即为10,因此打算开第10个分组时,会被弹回,数组不会越界
    dfs(1, 0, 0, 0);
	printf("%lld\n", ans);
	return 0;
}

参考文献
AcWing 1118. 分成互质组(算法提高课)y总视频讲解

AcWing 1118. 分成互质组题解

原创不易
转载请标明出处
如果对你有所帮助 别忘啦点赞支持哈
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞滕人生TYF

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值