# Divisibility

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1861    Accepted Submission(s): 721

Problem Description
As we know,the fzu AekdyCoin is famous of math,especially in the field of number theory.So,many people call him "the descendant of Chen Jingrun",which brings him a good reputation.
AekdyCoin also plays an important role in the ACM_DIY group,many people always ask him questions about number theory.One day,all members urged him to conduct a lesson in the group.The rookie daizhenyang is extremely weak at math,so he is delighted.
However,when AekdyCoin tells us "As we know, some numbers have interesting property. For example, any even number has the property that could be divided by 2.",daizhenyang got confused,for he don't have the concept of divisibility.He asks other people for help,first,he randomizely writes some positive integer numbers,then you have to pick some numbers from the group,the only constraint is that if you choose number a,you can't choose a number divides a or a number divided by a.(to illustrate the concept of divisibility),and you have to choose as many numbers as you can.
Poor daizhenyang does well in neither math nor programming.The responsibility comes to you!

Input
An integer t,indicating the number of testcases,
For every case, first a number n indicating daizhenyang has writen n numbers(n<=1000),then n numbers,all in the range of (1...2^63-1).

Output
The most number you can choose.

Sample Input
1 3 1 2 3

Sample Output
2 Hint: If we choose 2 and 3,one is not divisible by the other,which is the most number you can choose.

Author
DaiZhenyang@BUPT

Source

Recommend
lcy

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std;
__int64 tm[1006];
__int64 vis[1006];
__int64 tol[1006];
int max(int a,int b)
{return a<b?b:a;}
int main()
{
__int64 t;
scanf("%I64d",&t);
__int64 i,j,k;
__int64 n;
while(t--)
{
scanf("%I64d",&n);
for (i=1;i<=n;i++)
{
scanf("%I64d",&tm[i]);
}
sort(tm+1,tm+1+n);

for (i=1;i<=n;i++)	//假如选了第i个
{
tol[i]=1;
memset(vis,0,sizeof(vis));
for(j=i+1;j<=n;j++)
{
if (vis[j]|| tm[j]%tm[i]==0 )  //与第i个冲突的就不能选
continue;
for (k=j+1;k<=n;k++)
{
if (tm[k]%tm[j]==0)   //j与i不冲突，选了j,现在要把与j冲突的都删掉
vis[k]=1;

}
tol[i]++; //可以选第j个，那么选第i个的方案最后答案会加1
}
}
__int64 ans=tol[1];
for (i=1;i<=n;i++)
ans=max(tol[i],ans);
printf("%I64d\n",ans);
}
return 0;
}

3的行 对应3 6的列是1

6的行 对应 2 3 6的列是1

（这里特别的，选3选6对于个数没有区别，但是如果输出结果的话可能会有问题）

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;

typedef long long LL;
const int M=1e3+5;
const int MN=M;
const int MM=M;
const int MNN=MN*MM+MM; //最大点数
LL nu[M];

struct DLX
{
int n,m,si;//n行数m列数si目前有的节点数
//十字链表组成部分
int U[MNN],D[MNN],L[MNN],R[MNN],Row[MNN],Col[MNN];
//第i个结点的U向上指针D下L左R右，所在位置Row行Col列
int H[MN],S[MM]; //记录行的选择情况和列的覆盖情况
int ansd,ans[MN];//ansd最小步数，需要初始化
void init(int _n,int _m)  //初始化空表
{
n=_n;
m=_m;
for(int i=0;i<=m;i++) //初始化第一横行（表头）
{
S[i]=0;
U[i]=D[i]=i;      //目前纵向的链是空的
L[i]=i-1;
R[i]=i+1;         //横向的连起来
}
R[m]=0;L[0]=m;
si=m;                 //目前用了前0~m个结点
for(int i=1;i<=n;i++)
H[i]=-1;
}
void link(int r,int c)    //插入点(r,c)
{
++S[Col[++si]=c];     //si++;Col[si]=c;S[c]++;
Row[si]=r;
D[si]=D[c];
U[D[c]]=si;
U[si]=c;
D[c]=si;
if(H[r]<0)
H[r]=L[si]=R[si]=si;
else
{
R[si]=R[H[r]];
L[R[H[r]]]=si;
L[si]=H[r];
R[H[r]]=si;
}
}
void remove(int c)
{
for(int i=D[c];i!= c;i= D[i])
L[R[i]]=L[i],R[L[i]]=R[i];
}
void resume(int c)
{
for(int i=U[c];i!= c;i=U[i])
L[R[i]]=R[L[i]]=i;
}
int h() //估值
{
int ret=0;
for(int c=R[0];c!=0;c=R[c])
ret++;
return ret;
}
void dance(int d)
{
if(d+h()<=ansd)  //利用A*优化
return;
if(R[0]==0)
{
//            cout<<d<<endl;
//            for(int i=0;i<d;i++)
//                cout<<ans[i]<<" ";
//            cout<<endl;
if(ansd<d)
ansd=d;
return;
}
int c=R[0];
for(int i=R[0];i!=0;i=R[i])
if(S[i]<S[c])
c=i;
for(int i=D[c];i!=c;i=D[i])
{
//ans[d]=Row[i];
remove(i);
for(int j=R[i];j!=i;j=R[j])
remove(j);
dance(d+1);
for(int j=L[i];j!=i;j=L[j])
resume(j);
resume(i);
}
}
}dlx;

int main()
{
int t;
int n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%I64d",&nu[i]);
dlx.init(n,n);
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
if(nu[i]%nu[j]==0||nu[j]%nu[i]==0)
{
}
}
dlx.ansd=0;
dlx.dance(0);
printf("%d\n",dlx.ansd);
}
return 0;
}

bool v[MNN];
int h() //估值
{
int ret=0;
for(int c=R[0];c!=0;c=R[c])
v[c]=1;
for(int c=R[0];c!=0;c=R[c])
if(v[c])
{
ret++;
v[c]=0;
for(int i=D[c];i!=c;i=D[i])
for(int j=R[i];j!=i;j=R[j])
v[Col[j]]=0;
}
return ret;
}