zoukankan      html  css  js  c++  java
  • HDU 3335 Divisibility dancing links 重复覆盖

    分析:

    dlx重复覆盖的巧用,重复覆盖的原理恰好符合本题的筛选方式,即选择一个数后,该数的倍数或约数可以保证在之后的搜索中不会被选择
    于是修改一下启发函数,求解最大的重复覆盖即可。
     
    其实不一定不被选择,只是选择以后,要么达不成目标,要不达到目标,也不如不选择更优
     
    举下面的例子
    3
    2 3 6
    答案一看就是 2
    初始的dancing links的表示是这样的
          2   3   6
    2    1   0   1
    3    0   1   1
    6    1   1   1
    然后肯定先选第一列进行删
    删 第一行时
     
    得到
         2   3   6
    2    0   0   0
    3    0   1   0
    6    0   1   0
    此时要么删第二行,要么删第三行,所以6对应的第三行也是可以选的,只是选了第三行,对答案没有影响
     
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<cstdlib>
    #include<algorithm>
    #include<vector>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    const int N=1e6+5;
    const double eps=1e-8;
    int n,m,sz,k;
    int u[N],l[N],r[N],d[N];
    int h[1005],s[1005],col[N];
    void init()
    {
        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;
        sz=m;
        for(int i=1; i<=n; ++i)
            h[i]=-1;
    }
    void link(int x,int y)
    {
        ++sz;
        ++s[y],col[sz]=y;
        u[sz]=u[y],d[u[y]]=sz;
        d[sz]=y,u[y]=sz;
        if(h[x]==-1)h[x]=l[sz]=r[sz]=sz;
        {
            l[sz]=l[h[x]];
            r[l[h[x]]]=sz;
            r[sz]=h[x];
            l[h[x]]=sz;
        }
    }
    void del(int y)
    {
        for(int i=d[y]; i!=y; i=d[i])
            r[l[i]]=r[i],l[r[i]]=l[i];
    }
    void resume(int y)
    {
        for(int i=d[y]; i!=y; i=d[i])
            r[l[i]]=l[r[i]]=i;
    }
    int f()
    {
        int ret=0;
        for(int i=r[0];i;i=r[i])++ret;
        return ret;
    }
    int ans;
    void dance(int pos)
    {
        if(pos+f()<=ans)return;
        if(!r[0])
        {
            ans=max(pos,ans);
            return;
        }
        int t=r[0];
        for(int i=r[0]; i!=0; i=r[i])
            if(s[i]<s[t])t=i;
        for(int i=d[t]; i!=t; i=d[i])
        {
            del(i);
            for(int j=r[i]; j!=i; j=r[j])
                del(j);
            dance(pos+1);
            for(int j=l[i]; j!=i; j=l[j])
                resume(j);
            resume(i);
        }
    }
    LL a[1005];
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
           for(int i=1;i<=n;++i)
             scanf("%I64d",&a[i]);
           sort(a+1,a+1+n);
           m=n;
           init();
           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)
                link(i,j);
           ans=0;
           dance(0);
           printf("%d
    ",ans);
        }
        return 0;
    }
    View Code
     
  • 相关阅读:
    [年报阅读] 中国银行业监督管理委员会2009年报(1)
    囧事
    [论文收集] 2009年|国内计算机方向三大学报|Web Service相关论文
    打开那扇窗
    初生牛犊不怕虎
    忘却的纪念
    Java JDBC学习
    Java数组学习
    如何清晰地思考:近一年来业余阅读的关于思维方面的知识结构整理(附大幅思维导图)
    管理类文件
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/5293822.html
Copyright © 2011-2022 走看看