DFS——kotori和素因子
题目描述
kotori 拿到了一些正整数。她决定从每个正整数取出一个素因子。但是,kotori 有强迫症,她不允许两个不同的正整数取出相同的素因子。
她想知道,最终所有取出的数的和的最小值是多少?
注:若 a%k == 0,则称 k 是 a 的因子。若一个数有且仅有两个因子,则称其是素数。显然 1 只有一个因子,不是素数。
输入描述
第一行一个正整数 n,代表 kotori 拿到正整数的个数。
第二行共有 n 个数 ai,表示每个正整数的值。
保证不存在两个相等的正整数。
1 <= n <= 10
2 <= ai <= 1000
输出描述
一个正整数,代表取出的素因子之和的最小值。若不存在合法的取法,则输出-1。
示例
输入 1
4
12 15 28 22
输出 1
17
说明 1
分别取3,5,7,2,可保证取出的数之和最小
输入 2
5
4 5 6 7 8
输出
-1
备注
1 <= n <= 10
2 <= ai <= 1000
分析
先找到每个数的素因子,然后 dfs 搜索满足条件的最小值,若不存在,则输出 -1。
#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
int n,a[1005],vis[1005],ans=inf;
vector<int> f[15];
void dfs(int n,int sum)
{
if(ans<=sum){
return ;
}
if(n==0){
ans=sum;
}
else{
for(int i=0;i<f[n].size();i++){
if(!vis[f[n][i]]){
vis[f[n][i]]=1;
dfs(n-1,sum+f[n][i]);
vis[f[n][i]]=0;
}
}
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){
int m=a[i];
for(int j=2;j<=m/j;j++){
if(m%j==0){
f[i].push_back(j);
while(!(m%j)){
m/=j;
}
}
}
if(m>1){
f[i].push_back(m);
}
}
dfs(n,0);
if(ans==inf){
cout<<-1<<endl;
}
else{
cout<<ans<<endl;
}
return 0;
}