题意:给你一个序列,假设其中有两个数相加为素数,叫做一个匹配。求有多少个匹配。
一开始就想歪了(别想多),往DP想,结果真被我推出来了。。
一开始以为是设dp[i,j]表示i到j有多少个匹配,然而最后发现错了。。
正解是吧任意两个为匹配的数连边,做最大匹配。。(其实超级显然就是我一开始想歪了。。。。)
顺便复习一波最大匹配。。。
r
head,go,next:Array[0..100000]of longint;
vis,pd,jud,data,bo,a:Array[0..1000]of longint;
i,j,k,n,m,tot,ans:longint;
function prm(x:longint):boolean;
var
i:longint;
begin
if x=1 then exit(false);
for i:=2 to trunc(sqrt(x)) do
if x mod i=0 then exit(false);
exit(true);
end;
procedure add(x,y:longint);
begin
inc(tot);
go[tot]:=y;
next[tot]:=head[x];
head[x]:=tot;
end;
procedure dfs(x:longint);
var
i,v:longint;
begin
i:=head[x];
while i<>0 do
begin
v:=go[i];
if 0=vis[v] then
begin
vis[v]:=1;
if pd[x]=0 then pd[v]:=1
else pd[v]:=0;
dfs(v);
if (pd[v]<>pd[x]) and(jud[x]=0)and(jud[v]=0)then
begin
inc(ans);
jud[x]:=1;
jud[v]:=1;
end;
end;
i:=next[i];
end;
end;
begin
assign(input,'prime.in');
assign(output,'prime.out');
reset(input);
rewrite(output);
readln(n);
for i:=1 to n do
read(a[i]);
for i:=1 to n do
for j:=i+1 to n do
begin
if prm(a[i]+a[j])then
begin
add(i,j);
add(j,i);
bo[i]:=1;
bo[j]:=1;
end;
end;
for i:=0 to 1000 do pd[i]:=-1;
for i:=1 to n do
if (bo[i]<>0)and(pd[i]=-1) then
begin
pd[i]:=0;
dfs(i);
end;
writeln(ans);
end.