[kuangbin]专题三 Dancing Links Divisibility HDU - 3335【重复覆盖】

【题目描述】
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.
据我所知,the fzu AekdyCoin以数学出名,特别是在数论领域。所以很多人叫他"the descendant of Chen Jingrun"。
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.
AekdyCoin在ACM_DIY群中扮演着重要的角色,很多人总是问他关于数论的问题。有一天,所有人都希望他在群里上课。菜鸟daizhenyang数学非常薄弱,所以他很高兴。
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.
但是,当AekdyCoin告诉我们“如我们所知,有些数字具有有趣的性质。例如,任何偶数都具有可除以2的属性”,daizhenyang感到十分困惑了,因为他没有可除性的概念。他向其他人求助,首先,他随机地写了一些正整数,然后你需要从中挑选一些数字,唯一的限制是,如果选择数字a,则不能选择一个数字除以a或一个数字被a除(用来说明可除性的概念),你必须选择尽可能多的数字。
Poor daizhenyang does well in neither math nor programming.The responsibility comes to you!
daizhenyang既不擅长数学,也不擅长编程。责任就在你身上!

【输入】
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).
一个整数t,表示测试样例的个数。
对于所有样例,第一个数字n表示daizhenyang写下n个数,(n<=1000),然后n个数字,都在1…2^63-1的范围内。

【输出】
The most number you can choose.
你可以选择的最多的数字。

【样例输入】
1
3
1 2 3

【样例输出】
2

【样例提示】
If we choose 2 and 3,one is not divisible by the other,which is the most number you can choose.
如果我们选择2和3,一个都不能被其他的整除,这是你能选择的最多的数字。

题目链接:https://cn.vjudge.net/problem/HDU-3335

一开始一直觉得是精确覆盖问题,后来发现是重复覆盖

代码如下:

#include 
using namespace std;
typedef long long ll;
static const int MAXM=1000+10;
static const int MAXN=1000+10;
static const int MAXNODE=MAXN*MAXM;
ll a[MAXM];
struct DLX{
    int n,m,size;
    int U[MAXNODE],D[MAXNODE],R[MAXNODE],L[MAXNODE],Row[MAXNODE],Col[MAXNODE];
    int H[MAXN],S[MAXM];
    int ansd,ans[MAXN];
    bool vis[MAXNODE];
    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;
        size=m;
        for(int i=1;i<=n;i++)
            H[i]=-1;
    }
    void Link(int r,int c)
    {
        ++S[Col[++size]=c];
        Row[size]=r;
        D[size]=D[c];
        U[D[c]]=size;
        U[size]=c;
        D[c]=size;
        if(H[r]<0)
            H[r]=L[size]=R[size]=size;
        else
        {
            R[size]=R[H[r]];
            L[R[H[r]]]=size;
            L[size]=H[r];
            R[H[r]]=size;
        }
    }
    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 f()
    {
        int res=0;
        for(int i=R[0];i!=0;i=R[i])
            vis[i]=true;
        for(int i=R[0];i!=0;i=R[i])
            if(vis[i])
            {
                res++;
                vis[i]=false;
                for(int j=D[i];j!=i;j=D[j])
                    for(int t=R[j];t!=j;t=R[t])
                        vis[Col[t]]=false;
            }
        return res;
    }
    void Dance(int d)
    {
        if(d+f()<=ansd)
            return;
        if(R[0]==0)
        {
            if(d>ansd)
                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])
        {
            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);
        }
        return;
    }
};
DLX dlx;
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0),cout.tie(0);
    int T;
    cin>>T;
    while(T--)
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
            cin>>a[i];
        dlx.init(n,n);
        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.Link(i,j);
        dlx.ansd=0;
        dlx.Dance(0);
        cout<<dlx.ansd<<endl;
    }
    return 0;
}

你可能感兴趣的:(DLX)