zoj2479 Cover the Rectangular Ground

肯定是dfs搜一下的,但是呢存在一个很大的剪枝,也就是面积必定要是相等的,那么如何去操作呢,可以想到的是二进制枚举选取的方法,然后把方法中选取的矩形面积求和并判断一下即可,然后dfs搜索,要注意的是,需要维持现状的变量在变化之前一定要记录,要变回来时,一定要变回来,另外在dfs中还可以判断覆盖是否合理,以及是否已经没有可找到的空白区域。

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<string>
#include<set>
#include<algorithm>
#include<vector>
#include<queue>
#include<list>
#include<cmath>
#include<cstring>
#include<map>
#include<stack>
using namespace std;
#define INF 0x3f3f3f3f
#define maxn 2005
#define ull unsigned long long
#define ll long long
#define hashmod 99999839
#define mod 9997
int T,n,m,q,x[15],y[15],p[15],sx,sy,b;
int a[25][25];
bool f[15],ans;
bool overlap(int i,int v,int t){
    int ex = x[i],ey = y[i];
    if(v) swap(ex,ey);
    if(sx + ex - 1 >= n || sy + ey - 1 >= m) return false;
    for(int j = sx;j < sx + ex;++j){
        for(int k = sy;k < sy + ey;++k){
            if(t && a[j][k]) return false;
        }
    }
    for(int j = sx;j < sx + ex;++j){
        for(int k = sy;k < sy + ey;++k){
            a[j][k] = t;
        }
    }
    return true;
}
bool findempty(){
    for(int i = sx;i < n;++i){
        for(int j = 0;j < m;++j){
            if(!a[i][j]){
                sx = i,sy = j;
                return true;
            }
        }
    }
    return false;
}
bool check(){
    for(int i = 0;i < n;++i){
        for(int j = 0;j < m;++j){
            if(!a[i][j]) return false;
        }
    }
    return true;
}
void dfs(){
    bool flag = false;
    for(int i = 0;i < q;++i){
        if((b & p[i]) && !f[i]){
            flag = true;
            f[i] = true;
            int tx = sx,ty = sy;
            if(overlap(i,0,1)){
                if(findempty()) dfs();
                else{
                    ans = true;
                    return;
                }
                if(ans) return;
                sx = tx,sy = ty;
                overlap(i,0,0);
            }
            if(!overlap(i,1,1)){
                f[i] = false;
                continue;
            }
            if(findempty()) dfs();
            else{
                ans = true;
                return;
            }
            if(ans) return;
            sx = tx,sy = ty;
            overlap(i,1,0);
            f[i] = false;
        }
    }
    if(!flag && check()) ans = true;
}
bool solve(){
    for(int i = 0;i < p[q];++i){//枚举选取哪一些
        int s = 0;
        for(int j = 0;j < q;++j){
            if(i & p[j]) s = s + x[j] * y[j];
        }
        if(s != n * m) continue;
        b = i;
        ans = false;
        sx = sy = 0;
        dfs();
        if(ans) return true;
    }
    return false;
}
int main(){
 /*submit failed*/
 /*submit failed*/
 /*submit failed*//*submit failed*//*submit failed*/
    freopen("a.in","r",stdin);
    freopen("b.out","w",stdout);
    cin >> T;
    p[0] = 1;
    for(int i = 1;i <= 15;++i) p[i] = p[i - 1] << 1; 
    while(T--){
        scanf("%d%d",&n,&m);
        cin >> q;
        for(int i = 0;i < q;++i){
            scanf("%d%d",&x[i],&y[i]);
        }
        memset(a,0,sizeof(a));
        memset(f,false,sizeof(f));
        if(solve()) puts("YES");
        else puts("NO");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zhuiyicc/p/9494900.html