北京信息科技大学第十一届程序设计竞赛E-- kotori和素因子(深搜)

链接:https://ac.nowcoder.com/acm/contest/940/E

题目描述

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

输出

复制
17

说明

分别取3,5,7,2,可保证取出的数之和最小
示例2

输入

复制
5
4 5 6 7 8

输出

复制
-1

备注:

1<=n<=10

2<=ai<=1000


思路:对每个数先进行拆分素数,然后暴力搜就行。
代码:
#include<bits/stdc++.h> 
using namespace std;
#define LL long long
#define INF 2000000000
#define eps 1e-8
#define pi  3.141592653589793
const LL mod = 1e9+7;
int k,prime[200],x[11],n; 
int mp[1001],ans = 100000000;
vector<int>v[11];
void init(){
    k = 0;
    prime[k] = 2;k++;
    prime[k] = 3;k++;
    for(int i = 5 ; i <= 1100 ; i++){
        int end = sqrt(i);
        int flag = 1;
        for(int j = 2 ; j <= end ; j++){
            if(i%j == 0){
                flag = 0;break;
            }
        } 
        if(flag == 1) {
            prime[k]=i;
            k++;
        }
    }
}
void dfs(int dep,int sum){
    if(dep == n){
        ans = min(ans,sum);return;
    }
    for(int i = 0 ; i < v[dep].size() ; i ++){
        if(!mp[v[dep][i]]){
            mp[v[dep][i]] = 1;
            dfs(dep+1,sum+v[dep][i]);
            mp[v[dep][i]] = 0;
        }
    }
}
int main()
{
    init();
    scanf("%d",&n);
    int flag = 1; 
    memset(mp,0,sizeof(mp));
    for(int i = 0 ; i < n ; i ++){
        scanf("%d",&x[i]);
        for(int j = 0 ; j < k ; j++){
            int number = x[i];
            if(number%prime[j] == 0){
                v[i].push_back(prime[j]);

                while(number%prime[j] == 0){
                    number/=prime[j];
                }
            }
            if(number == 1)break;
        }
    }
    dfs(0,0);
    printf("%d\n",ans == 100000000?-1:ans);
}
/*
5
4 5 66 29 124
*/
 
  
 
 

猜你喜欢

转载自www.cnblogs.com/Esquecer/p/11107164.html