题目
题解
因为同奇偶的数相加一定是偶数,所以一定是合数,(1+1特判)
我们可以把序列中的分为奇数和偶数两部,并可以确定每个部之间肯定不可以都选,所以我们就把它转换成了一个二分图的问题。
我们再将两个数相加可能为合数的情况建边,再求一个最大独立子集就可以了。
#include<bits/stdc++.h>
using namespace std;
int a[3005];
int b[3005];
int t[3005];
int n=0,m=0;
int len;
bool p[1000005]={
};
void Prime(){
for(int i=2;i<=200000;i++){
if(p[i])
continue;
for(int j=i*2;j<=200000;j+=i)
p[j]=1;
}
}
int vis[3005][3005]={
};
vector<int> v[3005];
int flag[3005]={
};
int f[3005]={
};
int ans=0;
bool DFS(int x){
for(int i=0;i<v[x].size();i++){
int y=v[x][i];
if(f[y])
continue;
f[y]=1;
if(!flag[y]||DFS(flag[y])){
flag[y]=x;
return 1;
}
}
return 0;
}
void Work(){
bool f=1;
for(int i=1;i<=len;i++){
if(t[i]==1){
if(f)
a[++n]=t[i];
f=0;
continue;
}
if(t[i]%2)
a[++n]=t[i];
else
b[++m]=t[i];
}
}
int main(){
Prime();
cin>>len;
for(int i=1;i<=len;i++){
scanf("%d",&t[i]);
}
Work();
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(!p[a[i]+b[j]]){
v[i].push_back(j);
}
}
}
memset(flag,0,sizeof flag);
for(int i=1;i<=n;i++){
memset(f,0,sizeof f);
if(DFS(i))
ans++;
}
printf("%d\n",n+m-ans);
return 0;
}