v是u的儿子当且仅当u整除v并且加上v之后,所以v的乘积能被u整除
注意ai恰好是质数的情况
开始企图O(n^n),TLE了,O(n!)枚举,姿势对了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
#define ll long long
#define N 1000055
ll a[100],th[11];
int n;
int prime[N],cnt,isprime[N];
int num[11],temp[11][11];
int p[11];int ans;
int cal(ll nn)
{
ll k=nn;int res=0;
for(int i=0;(ll)prime[i]*prime[i]<=k;++i)
if(k%prime[i]==0)
{
do{
k/=prime[i];
res++;
}while(k%prime[i]==0);
}
if(k>1) res++;
return res;
}
void solve(int pos,int now)// i, i single, 0-n-1 tie
{
if(pos==n)
{
bool f=true;
for(int i=1;i<n;++i)
if(p[i]==i)
{
f=false;break;
}
if(!f) now++;
ans=min(ans,now);
return;
}
if(pos==0)
{
p[pos]=pos;
if(num[pos]==1) now=1;
else now=num[pos]+1;
solve(pos+1,now);
}
else
{
int add=0;
for(int i=0;i<pos;++i)
if(a[i]%a[pos]==0)
{
temp[i][++temp[i][0]]=pos;
ll e=1;bool f=true;
for(int k=1;k<=temp[i][0];++k){
if(e>a[i]/a[temp[i][k]])
{f=false; break;}
e*=a[temp[i][k]];
}
if(a[i]%e) f=false;
if(!f)
{
--temp[i][0];continue;
}
if(num[pos]>1) add=1;
else add=0;
p[pos]=i;
solve(pos+1,now+add);
--temp[i][0];
}
p[pos]=pos;
add=num[pos];
if(num[pos]>1) add++;
solve(pos+1,now+add);
}
}
int main ()
{
for(int i=2;i<N;++i)
if(!isprime[i])
{
prime[cnt++]=i;
for(int j=i;j<N;j+=i)
isprime[j]=1;
}
cin>>n;
for(int i=0;i<n;++i)
cin>>a[i];
for(int i=0;i<n-1;++i)
{
int idx=i;
for(int j=i+1;j<n;++j)
if(a[j]>a[idx])
idx=j;
if(idx!=i) swap(a[i],a[idx]);
}
for(int i=0;i<n;++i) num[i]=cal(a[i]);
if(n==1)
{
if(num[0]==1)
cout<<1;
else cout<<num[0]+1;
return 0;
}
ans=1000000000;
solve(0,0);
cout<<ans;
return 0;
}