/*
分析:
二分匹配。
太2了,一看到有矛盾关系瞬间就想到二分匹配了,可是太久
没做过二分匹配的题了,竟然没有想出来怎么建图?!我以前做恁
多二分匹配都白做了么囧~、都还给 OJ 了么T^T。。。
这个题中,数字之间的关键关系是倍数么,所以用最大的(或
最小的)数,按照a是b的整数倍(或a是b的因子)的关系跑下去,最
少需要跑ans条这样的路,ans既为答案。
这个解释应该够形象了,就是跑路么,最少的路把所有的点都
经过就行了,所以就是最少路径覆盖了。不难,不过还是贴出来,
告诉自己自己有多2&&多白痴,警示一下囧~。。。再说也有一段没
有发blog了,发一个,证明在ACM这条道儿上、lz还顽强的活着= =III。
2013-05-19
*/
分析:
二分匹配。
太2了,一看到有矛盾关系瞬间就想到二分匹配了,可是太久
没做过二分匹配的题了,竟然没有想出来怎么建图?!我以前做恁
多二分匹配都白做了么囧~、都还给 OJ 了么T^T。。。
这个题中,数字之间的关键关系是倍数么,所以用最大的(或
最小的)数,按照a是b的整数倍(或a是b的因子)的关系跑下去,最
少需要跑ans条这样的路,ans既为答案。
这个解释应该够形象了,就是跑路么,最少的路把所有的点都
经过就行了,所以就是最少路径覆盖了。不难,不过还是贴出来,
告诉自己自己有多2&&多白痴,警示一下囧~。。。再说也有一段没
有发blog了,发一个,证明在ACM这条道儿上、lz还顽强的活着= =III。
2013-05-19
*/
#include"iostream"
#include"cstdio"
#include"cstring"
#include"algorithm"
using namespace std;
const int N=1011;
int n,match[N],vis[N];
struct Edge{
int v,next;
}edge[N*N];
int tot,head[N];
void add(int a,int b){
edge[tot].v=b;edge[tot].next=head[a];head[a]=tot++;
}
void build_map()
{
int i,l,cnt;
__int64 a[N],b[N];
tot=0;
memset(head,-1,sizeof(head));
for(i=0;i<n;i++) scanf("%I64d",&a[i]);
sort(a,a+n);
b[0]=a[0];
cnt=1;
for(i=1;i<n;i++)
{
if(a[i]==a[i-1]) continue;
b[cnt++]=a[i];
}
n=cnt;
for(i=0;i<n;i++)
for(l=0;l<n;l++)
{
if(i==l) continue;
if(b[i]%b[l]==0) add(i,l);
}
}
int dfs(int k)
{
int j,v;
for(j=head[k];j!=-1;j=edge[j].next)
{
v=edge[j].v;
if(vis[v]) continue;
vis[v]=1;
if(match[v]==-1 || dfs(match[v]))
{
match[v]=k;
return 1;
}
}
return 0;
}
int main()
{
int T;
int i;
cin>>T;
while(T--)
{
cin>>n;
build_map();
int ans=0;
memset(match,-1,sizeof(match));
for(i=0;i<n;i++)
{
memset(vis,0,sizeof(vis));
ans+=dfs(i);
}
cout<<n-ans<<endl;
}
return 0;
}