acwing 1118. 分成互質組(dfs搜尋+剪枝)
阿新 • • 發佈:2022-03-19
目錄
題目描述
給定 nn 個正整數,將它們分組,使得每組中任意兩個數互質。
至少要分成多少個組?
輸入格式
第一行是一個正整數 nn。
第二行是 nn 個不大於10000的正整數。
輸出格式
一個正整數,即最少需要的組數。
資料範圍
1≤n≤10
輸入樣例:
6 14 20 33 117 143 175
輸出樣例:
3
dfs剪枝搜尋
分析
對於每個數
- 如果他和某一組內所有數互質,就可以將它加到這個組;然後回溯
- 新開一個組,把這個數加到新的組
對於如何判斷互質:用定義
兩個數互質:就是兩個數的最大公約數是1
程式碼
#include<iostream> #include<cstdio> #include<vector> using namespace std; int gcd(int a, int b) { return b ? gcd(b, a % b) : a; } bool isZ(int a, int b) { if(gcd(a, b) > 1) return false; else return true; } int ans = 0x3f3f3f3f; vector<int> h[12]; int a[12]; int n; void dfs(int u, int k) { if(k >= ans) return; // 剪枝 if(u >= n) { ans = min(ans, k); return; } for(int i = 0; i < k; i++) { vector<int> tmp = h[i]; // 第k組有的所有互質的數 bool flag = true; for(int j = 0; j < tmp.size(); j++) { if(!isZ(a[u], tmp[j])) { flag = false; break; } } if(flag) { h[i].push_back(a[u]); dfs(u+1, k); h[i].pop_back(); // 恢復現場 } } h[k].push_back(a[u]); dfs(u+1, k+1); h[k].pop_back(); } int main() { cin >> n; for(int i = 0; i < n; i++) cin >> a[i]; dfs(0, 0); cout << ans; return 0; }