zoukankan      html  css  js  c++  java
  • (中等) HDU 3335 , DLX+重复覆盖。

      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!
     
      题目就是找到几个数,然后他们之间都不能整除。。。。。。
      这个题卡了一段时间。。。。。。看了大神们的题解之后才会的。。。。。。
      虽然这个题目让我们求得是最大值,其实是在最小值里面的最大值,DLX可重复覆盖的模板是为了找到最小值,所以找到最小值的过程中默认了选择某一个之后和他相关连的都不用在选择了。。。而这样正好就符合了这个题目的要求,也就是我们以找最小值的方法,找到的值就是符合题意的一个值。。。。。。然后改一下getH()函数,也就是获得启发值得函数,就OK了。。。
      构造的话就是n行n列就好,代表这n个数,(所以要求每一列都要被覆盖掉。。。。。。)。。。。。。
     
    代码如下:
    #include<iostream>
    #include<cstring>
    
    using namespace std;
    
    const int MaxN=1010;
    const int MaxM=1010;
    const int MaxNode=MaxN*MaxM;
    
    struct DLX
    {
        int L[MaxNode],R[MaxNode],U[MaxNode],D[MaxNode],col[MaxNode];
        int H[MaxN],S[MaxM];
        int ansnum;
        int n,m,size;
    
        void init(int _n,int _m)
        {
            n=_n;
            m=_m;
    
            for(int i=0;i<=m;++i)
            {
                U[i]=D[i]=i;
                L[i]=i-1;
                R[i]=i+1;
    
                S[i]=0;
            }
            L[0]=m;
            R[m]=0;
    
            size=m;
    
            ansnum=0;
    
            for(int i=0;i<=n;++i)
                H[i]=-1;
        }
    
        void Link(int r,int c)
        {
            col[++size]=c;
            ++S[c];
    
            U[size]=U[c];
            D[size]=c;
            D[U[c]]=size;
            U[c]=size;
    
            if(H[r]==-1)
                H[r]=L[size]=R[size]=size;
            else
            {
                L[size]=L[H[r]];
                R[size]=H[r];
                R[L[H[r]]]=size;
                L[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 getH()
        {
            int ret=0;
    
            for(int i=R[0];i!=0;i=R[i])
                ++ret;
    
            return ret;
        }
    
        void Dance(int d)
        {
            if(R[0]==0)
                if(d>ansnum)
                    ansnum=d;
    
            if(getH()+d<=ansnum)
                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);
            }
        }
    
    
    };
    
    DLX dlx;
    unsigned long long num[1010];
    int N;
    
    void slove()
    {
        dlx.init(N,N);
    
        for(int i=1;i<=N;++i)
            for(int j=1;j<=N;++j)
                if(num[i]%num[j]==0 || num[j]%num[i]==0)
                    dlx.Link(i,j);
    
        dlx.Dance(0);
    
        cout<<dlx.ansnum<<endl;
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
    
        int T;
        cin>>T;
    
        while(T--)
        {
            cin>>N;
    
            for(int i=1;i<=N;++i)
                cin>>num[i];
    
            slove();
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    原生js实现基本选择器
    javascript数组
    web中关于隐藏与显示
    CSS3 box-shadow(阴影使用)
    java中文件的I/O操作
    组件RecyclerView的应用(一)
    Android客户端与Eclipse服务器端的Socket通信
    C语言关于利用sscanf实现字符串相加减
    TabLayout和ViewPager简单实现页卡的滑动
    DrawerLayout的openDrawer()和closeDrawer()方法
  • 原文地址:https://www.cnblogs.com/whywhy/p/4263929.html
Copyright © 2011-2022 走看看