天天看點

HDU 3335 Divisibility

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.

dlx重複覆寫的巧用,重複覆寫的原理恰好符合本題的篩選方式,即選擇一個數後,該數的倍數或約數可以保證在之後的搜尋中不會被選擇

于是修改一下啟發函數,求解最大的重複覆寫即可。

#include<cstdio>
#include<vector>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll maxn = 5005;
int T, n, m, x, y, t, X, Y,tot;
ll a[maxn];

inline void read(int &ret)
{
	char c;
	do {
		c = getchar();
	} while (c < '0' || c > '9');
	ret = c - '0';
	while ((c = getchar()) >= '0' && c <= '9')
		ret = ret * 10 + (c - '0');
}

struct DLX
{
	#define maxn 500005
	#define F(i,A,s) for (int i=A[s];i!=s;i=A[i])
	int L[maxn], R[maxn], U[maxn], D[maxn];
	int row[maxn], col[maxn], ans[maxn], cnt[maxn];
	int n, m, num, sz;

	void add(int now, int l, int r, int u, int d, int x, int y)
	{
		L[now] = l;	R[now] = r;	U[now] = u;
		D[now] = d;   row[now] = x;  col[now] = y;
	}
	void reset(int n, int m)
	{
		num = 0x7FFFFFFF;
		this->n = n;	this->m = m;
		for (int i = 0; i <= m; i++)
		{
			add(i, i - 1, i + 1, i, i, 0, i);
			cnt[i] = 0;
		}
		L[0] = m; 	R[m] = 0; 	sz = m + 1;
	}
	void insert(int x, int y)
	{
		int ft = sz - 1;
		if (row[ft] != x)
		{
			add(sz, sz, sz, U[y], y, x, y);
			U[D[sz]] = sz; D[U[sz]] = sz;
		}
		else
		{
			add(sz, ft, R[ft], U[y], y, x, y);
			R[L[sz]] = sz; L[R[sz]] = sz;
			U[D[sz]] = sz; D[U[sz]] = sz;
		}
		++cnt[y];	++sz;
	}

	//精确覆寫
	void remove(int now)
	{
		R[L[now]] = R[now];
		L[R[now]] = L[now];
		F(i, D, now) F(j, R, i)
		{
			D[U[j]] = D[j];
			U[D[j]] = U[j];
			--cnt[col[j]];
		}
	}
	void resume(int now)
	{
		F(i, U, now)	F(j, L, i)
		{
			D[U[j]] = j;
			U[D[j]] = j;
			++cnt[col[j]];
		}
		R[L[now]] = now;
		L[R[now]] = now;
	}
	bool dfs(int x)
	{
		//if (x + A() >= num) return;
		if (x==n) { num = min(num, x); return true; }
		int now = R[0];
		if (now>n) return false;
		for (int i=R[0];i<=n;i=R[i]) if (cnt[now]>cnt[i]) now = i;
		remove(now);
		F(i, D, now)
		{
			ans[x] = row[i];
			F(j, R, i) remove(col[j]);
			if (dfs(x + 1)) return true;
			F(j, L, i) resume(col[j]);
		}
		resume(now);
		return false;
	}
	//精确覆寫

	//重複覆寫
	void Remove(int now)
	{
		F(i, D, now)
		{
			L[R[i]] = L[i];
			R[L[i]] = R[i];
		}
	}
	void Resume(int now)
	{
		F(i, U, now) L[R[i]] = R[L[i]] = i;
	}
	int vis[maxn];
	int flag[maxn];
	int A()
	{
		int dis = 0;
		F(i, R, 0) dis++;
		return dis;
	}
	void Dfs(int x)
	{
		if (!R[0]) num = max(num, x);
		else if (A()+x>num)
		{
			int now = R[0];
			F(i, R, 0) if (cnt[now]>cnt[i]) now = i;
			F(i, D, now)
			{
				Remove(i); F(j, R, i) Remove(j);
				Dfs(x + 1);
				F(j, L, i) Resume(j); Resume(i);
			}
		}
	}
	//重複覆寫

}dlx;

int main()
{
	read(T);
	while (T--)
	{
		scanf("%d", &n);
		dlx.reset(n,n);
		for (int i=1;i<=n;i++) scanf("%lld",&a[i]);
		for (int i=1;i<=n;i++)
			for (int j=1;j<=n;j++)
				if (a[i]%a[j]==0||a[j]%a[i]==0)
					dlx.insert(i,j);
		dlx.num=0;
		dlx.Dfs(0);
		printf("%d\n",dlx.num);
	}
	return 0;
}