洛谷P1034 矩形覆盖

洛谷P1034 矩形覆盖

这是一道简单的搜索题,但是非常难想到(据说当年的这题,全国没有一个人完全做对)。

首相我们来分析下,由于题目说矩形不能相互重合,即不能相交,并且k<=4。 那么我们可以分别写出矩形的排列方式。

1、当k=1时,就是一个大矩形,求所有点的左上右下的两个点。

2、当k=2时,有如下两个排列方式

洛谷P1034 矩形覆盖_第1张图片

那么怎么计算呢?

对于左图,我们先将原先的点,按照y坐标升序排序,然后循环选择中间点,1i之间用一个矩形,i+1n再用一个矩形。

而右图,按x坐标升序排序,之后的操作一样

3、当k=3时,有如下六种方式:

洛谷P1034 矩形覆盖_第2张图片

有了对k=2的分析基础,我相信,k=n的dfs深搜应该不难,就是一遍遍画矩形画下去,注意剪枝就行了,我自己写的时候,由于一开始没有在dfs中穿数组,导致每一遍for都要用一个sort,导致最后一个点超时了,后来改了改才过的。

其实仔细想想挺简单的。

上代码:

#include 
#define ull unsigned long long 
using namespace std;
const int maxn=1e2+7;
int n,k,ans=0x7fffffff;
struct Node{
    int x,y,id;
}node[maxn];
bool cmp(Node xx,Node yy){
    if(xx.x==yy.x)
        return xx.y<yy.y;
    return xx.x<yy.x;
}
bool cmp1(Node xx,Node yy){
    if(xx.y==yy.y)
        return xx.x<yy.x;
    return xx.y<yy.y;
}
void dfs(int ctk,int sum,int tp,Node n1[maxn],Node n2[maxn]){
    if(ctk>k || sum>ans)
        return;
    if(tp>n){
        if(ctk==k)
            ans=min(sum,ans);
        return;
    }
    int downx=0x7fffffff,downy=0x7fffffff,upx=-1,upy=-1;
    sort(n1+tp,n2+1+n,cmp);
    for(int i=tp;i<=n;i++){
        downx=min(node[i].x,downx);
        downy=min(node[i].y,downy);
        upx=max(node[i].x,upx);
        upy=max(node[i].y,upy);
        dfs(ctk+1,sum+(upx-downx)*(upy-downy),i+1,n1,n2);
    }
    downx=0x7fffffff,downy=0x7fffffff,upx=-1,upy=-1;
    sort(n2+tp,n2+n+1,cmp1);
    for(int i=tp;i<=n;i++){
        downx=min(node[i].x,downx);
        downy=min(node[i].y,downy);
        upx=max(node[i].x,upx);
        upy=max(node[i].y,upy);
        dfs(ctk+1,sum+(upx-downx)*(upy-downy),i+1,n1,n2);
    }
}
int main(){
    //freopen(".in","r",stdin);
    scanf("%d %d",&n,&k);
    for(int i=1;i<=n;i++){
        scanf("%d %d",&node[i].x,&node[i].y);
        node[i].id=i;
    }
    dfs(0,0,1,node,node);
    printf("%d",ans);
return 0;
}

i].id=i;
}
dfs(0,0,1,node,node);
printf("%d",ans);
return 0;
}


你可能感兴趣的:(DFS,洛谷,搜索)