• Posters TopCoder


    传送门

    分析

    首先我们不难想到1e4^5的暴力枚举,但显然这是不行的,于是我们考虑对于每一张海报肯定有一种最优情况使得它至少有一条边要么靠着板子的边要么靠着之前的某一张海报的边,这样我们便可以将复杂度优化了很多。我们再考虑将每一种情况进行哈希,这样便可以避免了如图一的情况(矩形中的数字是指这个矩形是第几个被添加进来的)

    图一

    我们看得出来这两种实际是一种情况,所以通过哈希我们可以避免重复搜索。在有了这些之后我们再在程序中加一些其它剪枝,用容斥统计答案就行了,详见代码。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    #define sp cout<<"---------------------------------------------------"<<endl
    #define uli long long
    const uli HASH=173;
    int n,m,k,a[10],b[10],x[10],y[10],ans;
    set<uli>vis;
    uli gethash(int msk){
        uli hsh=0;
        for(int i=1;i<k;i++)
        if(msk&(1<<i)){
              hsh=hsh*HASH+(uli)x[i]-(uli)x[0];
              hsh=hsh*HASH+(uli)y[i]-(uli)y[0];
        }else {
              hsh=hsh*HASH+(uli)n;
              hsh=hsh*HASH+(uli)m;
        }
        return hsh;
    }
    int getans(int msk){
        int i,j,res=0;
        for(i=msk;i>0;i=(i-1)&msk){
        int x1=-1,y1=-1,x2=n,y2=m;
        for(j=0;j<k;j++)
          if(i&(1<<j)){
              x1=max(x1,x[j]),y1=max(y1,y[j]);
              x2=min(x2,x[j]+a[j]-1);
              y2=min(y2,y[j]+b[j]-1);
          }
          if(__builtin_popcount(i)&1){
              res+=max(x2-x1+1,0)*max(y2-y1+1,0);
          }else res-=max(x2-x1+1,0)*max(y2-y1+1,0);
        }
        return res;
    }
    void fx(int);
    void work(int msk,int wh,int xx,int yy){
        if(yy<0||yy+b[wh]>m||xx<0||xx+a[wh]>n)return;
        x[wh]=xx;y[wh]=yy;
        int res=getans(msk|(1<<wh));
        ans=max(ans,res);
        for(int i=0;i<k;i++)
        if(i!=wh&&!(msk&(1<<i)))
            res+=a[i]*b[i];
        if(res<=ans)return;
        uli hsh=gethash(msk|(1<<wh));
        if(vis.find(hsh)==vis.end()){
            vis.insert(hsh);
            fx(msk|(1<<wh));
        }
    }
    void fy(int msk,int wh,int xx){
        int i;
        if(xx<0||xx+a[wh]>n)return;
        work(msk,wh,xx,0);
        work(msk,wh,xx,m-b[wh]);
        for(i=0;i<k;i++)
          if(msk&(1<<i)){
              work(msk,wh,xx,y[i]+b[i]);
              work(msk,wh,xx,y[i]-b[wh]);
          }
        }
    void fx(int msk){
        int i,j;
        for(i=0;i<k;i++)
        if(!(msk&(1<<i))){
              fy(msk,i,0);
              fy(msk,i,n-a[i]);
              for(j=0;j<k;j++)
                     if(msk&(1<<j)){
                            fy(msk,i,x[j]+a[i]);
                            fy(msk,i,x[j]-a[i]);
                     }
        }
    }
    class Posters {
        public:
          int maxCover(int wt,int ht,vector<int>pw,vector<int>ph){
             n=wt,m=ht,k=pw.size();
             for(int i=0;i<k;i++){
               a[i]=min(pw[i],n);
               b[i]=min(ph[i],m);
             }
             fx(0);
             return ans;
          }
    };
  • 相关阅读:
    webpack2.x抽取css
    window.print控制打印样式
    Vue2.x中的父子组件相互通信
    Vue2.x中的父组件数据传递至子组件
    NodeJs之fs的读写删移监
    设计
    mycat服务启动{管理模块启动过程}
    mycat初探
    zookeeper总结
    rocketmq总结
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9360251.html
Copyright © 2020-2023  润新知