zoukankan      html  css  js  c++  java
  • FZU 1686(重复覆盖)

    题目连接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=31370

    题意:用尽量少r*c的小矩形覆盖大矩形n*m中的所有1,将所有1转换成size列,然后以大矩形的每点当成小矩形r*c的左上角覆盖到的1当成一行,问题则转换成m*n行中选尽量少的行来覆盖所有列。。。

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <cmath>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cstdlib>
    #include <stack>
    #include <vector>
    #include <set>
    #include <map>
    #define LL long long
    #define mod 10007
    #define inf 0x3f3f3f3f
    #define N 100010
    #define FILL(a,b) (memset(a,b,sizeof(a)))
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    using namespace std;
    const int maxnode=250010;
    const int MaxN=510;
    const int MaxM=510;
    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];
        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;
        }
    
    
        bool vis[maxnode];
        int h()
        {
            int res=0;
            for(int c=R[0];c!=0;c=R[c])vis[c]=true;
            for(int c=R[0];c!=0;c=R[c])
            if(vis[c])
            {
                res++;
                vis[c]=false;
                for(int i=D[c];i!=c;i=D[i])
                    for(int j=R[i];j!=i;j=R[j])
                        vis[Col[j]]=false;
            }
            return res;
        }
        void Dance(int d)//d为递归深度
        {
            if(d+h()>=ansd)return;
            if(R[0]==0)//找到解
            {
                if(d<ansd)ansd=d;
                return;
            }
            //找S最小的C列
            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])//用结点i所在的行覆盖第c列
            {
                Remove(i);
                for(int j=R[i];j!=i;j=R[j])Remove(j);//删除节结点i所在行覆盖第c列
                Dance(d+1);
                for(int j=L[i];j!=i;j=L[j])Resume(j);// 恢复
                Resume(i);
            }
        }
    };
    DLX g;
    int id[20][20];
    int main()
    {
        int n,m,x,c,r;
        while(scanf("%d%d",&n,&m)>0)
        {
            int sz=0;
            for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                scanf("%d",&x);
                id[i][j]=x?++sz:0;
            }
            g.init(n*m,sz);
            scanf("%d%d",&r,&c);
            for(int i=1,num=1;i<=n;i++)
            for(int j=1;j<=m;j++,num++)
            {
                for(int x=0;x+i<=n&&x<r;x++)
                    for(int y=0;y+j<=m&&y<c;y++)
                    if(id[i+x][y+j])
                    g.Link(num,id[i+x][j+y]);
            }
            g.ansd=n*m;
            g.Dance(0);
            printf("%d
    ",g.ansd);
        }
    }
    View Code
  • 相关阅读:
    HDU 5912 Fraction (模拟)
    CodeForces 722C Destroying Array (并查集)
    CodeForces 722B Verse Pattern (水题)
    CodeForces 722A Broken Clock (水题)
    CodeForces 723D Lakes in Berland (dfs搜索)
    CodeForces 723C Polycarp at the Radio (题意题+暴力)
    CodeForces 723B Text Document Analysis (水题模拟)
    CodeForces 723A The New Year: Meeting Friends (水题)
    hdu 1258
    hdu 2266 dfs+1258
  • 原文地址:https://www.cnblogs.com/lienus/p/4246092.html
Copyright © 2011-2022 走看看