• COGS103&tyvj1899 [NOIP2002]矩形覆盖


    题目里给的范围是k<=4,但是官方数据并没有k==4的情况,导致一些奇奇怪怪的DP写法也能过。听说标程在k==4的时候有反例,掀桌….. 难怪COGS上k==4的数据答案是错的。

    还是好好写个搜索吧:网上写法很多.我是每次沿着一条平行于坐标轴的直线将点集分割成两部分,并枚举k个矩形如何在两边分配。边界为k==1,扫一遍所有点找到最小的矩形。细节看代码吧.

    但是这个搜索我也不能保证是对的,因为k==4有可能出现这种崎岖的最优方案:不存在一条平行于坐标轴且不和任何一个矩形相交的直线将4个矩形分成两部分.例如这样的最优方案:

    贴个代码吧:递归的时候为了处理“将点集分成两部分”调了一堆memcpy….好在递归层数和点数都不多,不然常数炸天....

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=55;
    int x[maxn],y[maxn],seq[maxn];
    inline int max(int a,int b){
        return a>b?a:b;
    }
    inline int min(int a,int b){
        return a<b?a:b;
    }
    bool cmp1(const int &a,const int &b){
        return x[a]<x[b];
    }
    bool cmp2(const int &a,const int &b){
        return y[a]<y[b];
    }
    struct node{
        int x1,y1,x2,y2;
        node(){}
        node(int a,int b,int c,int d){
            x1=a;y1=b;x2=c;y2=d;
        }
    }sol[10];int cnt=0;
    int work(int l,int r,int seq[]){
        int minx=0x7f7f7f7f,miny=0x7f7f7f7f,maxx=0,maxy=0;
        for(int i=l;i<=r;++i){//printf("seq%d
    ",seq[i]);
            minx=min(minx,x[seq[i]]);maxx=max(maxx,x[seq[i]]);
            miny=min(miny,y[seq[i]]);maxy=max(maxy,y[seq[i]]);
        }
        sol[++cnt]=node(minx,miny,maxx,maxy);
        return (maxx-minx)*(maxy-miny);
    }
    int s[1000][55];int tot=0;
    int dfs(int l,int r,int k,int seq[]){//printf("%d
    ",k);
        if(k==1){
            int tmp=work(l,r,seq);
            cnt--;
            return tmp;
        }else{
            int ans=0x7f7f7f7f;
            sort(seq+l,seq+r+1,cmp1);
            for(int i=l;i<r;++i){
                for(int j=1;j<k;++j){
                    ++tot;
                    memcpy(s[tot],seq,sizeof(int)*55);
                    ++tot;
                    memcpy(s[tot],seq,sizeof(int)*55);
                    if(x[seq[i]]!=x[seq[i+1]]){
                        int tmp=dfs(l,i,j,s[tot-1])+dfs(i+1,r,k-j,s[tot]);
                        ans=min(ans,tmp);
                    }
                    --tot;--tot;
                    //printf("---------------
    ");
                }
            }//printf("%d
    ",ans);
            sort(seq+l,seq+r+1,cmp2);
            for(int i=l;i<r;++i){
                for(int j=1;j<k;++j){
                    ++tot;
                    memcpy(s[tot],seq,sizeof(int)*55);
                    ++tot;
                    memcpy(s[tot],seq,sizeof(int)*55);
                    if(y[seq[i]]!=y[seq[i+1]]){
                        int tmp=dfs(l,i,j,s[tot-1])+dfs(i+1,r,k-j,s[tot]);
                        ans=min(ans,tmp);
                    }
                    --tot;--tot;
                    //printf("---------------
    ");
                }
            }//printf("%d
    ",ans);
            return ans;
        }
    }
    int main(){
        int n,k;
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;++i){
            scanf("%d%d",x+i,y+i);
        }
        for(int i=1;i<=n;++i){
            seq[i]=i;
        }
        printf("%d
    ",dfs(1,n,k,seq));
        return 0;
    }
  • 相关阅读:
    R: 聚类分析
    R: 主成分分析 ~ PCA(Principal Component Analysis)
    R: 关于 ggplot2 的初探
    R: 字符串处理包:stringr
    R: 用 R 查看、管理文件(夹)
    R: 关于文件 文件夹的处理:file.show() dir.create().....
    R: 绘图 pie & hist
    R: 绘图 barplot
    R: 对向量中的每个元素,检查其是否包含某个“单词”
    R: 一页显示多张图的方法
  • 原文地址:https://www.cnblogs.com/liu-runda/p/5990629.html
Copyright © 2020-2023  润新知