牛客 - 北京信息科技大学校赛 E题

题目:

链接: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

思考:
用vector来存每一个数的素因子,好像二维数组也可以,然后跑dfs求出最小解。

代码:

#include<iostream>
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<math.h>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn=1005;
const int inf=0x3f3f3f3f;
vector<int>u[maxn];
int vis[maxn],Prime[maxn],a[11],n;
int ans=inf;
void shai(){
	for(int i=0;i<maxn;i++) Prime[i]=1;
	for(int i=2;i*i<maxn;i++){
		if(Prime[i]){
			for(int j=i*2;j<maxn;j+=i) Prime[j]=0;
		}
	}
}
void dfs(int st,int sum){
	if(st==n){
		ans=min(ans,sum);
		return;
	}
	for(int i=0;i<u[st].size();i++){
		if(!vis[u[st][i]]){
			vis[u[st][i]]=1;
			dfs(st+1,sum+u[st][i]);
			vis[u[st][i]]=0;
		}
	}
}
int main(){
	cin>>n;
	shai();
	for(int i=0;i<n;i++) cin>>a[i];
	for(int i=0;i<n;i++){
		for(int j=2;j<=a[i];j++){
			if(a[i]%j==0&&Prime[j]){
				u[i].push_back(j);
			}
		}
	}
	dfs(0,0);
	if(ans==inf) cout<<"-1\n";
	else cout<<ans<<endl;
	return 0;
}

发布了43 篇原创文章 · 获赞 56 · 访问量 5124

猜你喜欢

转载自blog.csdn.net/tran_sient/article/details/97438867