• 题解 P1034 【矩形覆盖】


    (something~else:)

    看了一圈似乎没人用我的方法,有点小激动的我连忙跑过来码了份题解

    (ps:CSP2019~RP++)

    (problem)


    开始讲题

    看到数据范围是很水的(n<=50,k<=4),顿时感觉出题人良心,可以简单的想到应该有个(O(n^4))的正常算法

    (first)

    关键是怎么利用矩形的问题。

    对于矩形的确定,我们不能简单地被标题给带过去看成是“覆盖”了,其实换个角度想,矩形的覆盖可以看做矩形的“划分

    比如用(k)个矩形覆盖所有点,就是(k-1)划分整个图形使其成为(k)个矩形

    (second)

    想到划分的话就很容易想到可以有状态方程的设计:

    (f_{d1,d2,e1,e2,k})为横坐标上下界分别为(d2,d1),纵坐标上下界分别为(e1,e2)的点集划分(k)次的矩形覆盖面积最小值,则:

    [f_{d1,d2,e1,e2,k}=min(minlimits_{iin[d1,d2],jin[0,k)}(f_{d1,i,e1,e2,k-j-1}+f_{i+1,d2,e1,e2,j}),minlimits_{iin[e1,e2],jin[0,k)}(f_{d1,d2,e1,i,k-j-1}+f_{d1,d2,i+1,e2,j})) ]

    [ ext{边界:}f_{d1,d2,e1,e2,0}= ext{d1,d2,e1,e2内的点集的面积(这个应该都会算哈)} ]

    [ ext{目标:}f_{min_x,max_x,min_y,max_y,k-1} ext{这里的k是矩形数} ]

    关于(x_i,y_iin[0,500])可以离散化一下,这样就成功将复杂度化为(O(n^4))

    (third)

    祝大家(CSP2019~RP++)

    (forth)

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    inline int read()
    {
    	int x=0,f=1;
    	char ch=getchar();
    	for(;!isalnum(ch);ch=getchar()) if(ch=='-') f=-1;
    	for(;isalnum(ch);ch=getchar()) x=x*10+ch-'0';
    	return x*f;
    }
    const int xx=52;
    struct point
    {
    	int x,y;
    }d[xx],e[xx];
    int ans=0x7fffffff,n;
    inline bool cmp1(point a,point b){return a.x<b.x;}
    inline bool cmp2(point a,point b){return a.y<b.y;}
    inline int div(int d1,int d2,int e1,int e2,int k)
    {
    	int res=ans;
    	if(k)
    	{
    		for(register int i=d1;i<d2;++i)
    			for(register int j=0;j<k;++j)
    				res=min(res,div(d1,i,e1,e2,k-j-1)+div(i+1,d2,e1,e2,j));
    		for(register int i=e1;i<e2;++i)
    			for(register int j=0;j<k;++j)
    				res=min(res,div(d1,d2,e1,i,k-j-1)+div(d1,d2,i+1,e2,j));
    		return res;
    	}
    	int mxx=0,mnx=ans,mxy=0,mny=ans;
    	for(register int i=1;i<=n;++i)
    		if(d[i].x>=d[d1].x&&d[i].x<=d[d2].x)
    			if(d[i].y>=e[e1].y&&d[i].y<=e[e2].y)
    				mxx=d[i].x,mnx=min(mnx,d[i].x),mxy=max(mxy,d[i].y),mny=min(mny,d[i].y);
    	return (mxy-mny)*(mxx-mnx);
    }
    int main()
    {
    	n=read();int k=read();
    	for(register int i=1;i<=n;i++) d[i]=e[i]=(point){read(),read()};
    	sort(d+1,d+n+1,cmp1);
    	sort(e+1,e+n+1,cmp2);
    	ans=div(1,n,1,n,k-1);
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    [NOIP2013]花匠
    [NOIP2013]货车运输
    [NOIP2013]火柴排队
    [NOIP2012]疫情控制
    雷动WEBRTC产品
    WebRTC学习笔记_Demo收集
    Red5的直播与点播的压力测试(并发数的测试)
    Apache Tomcat8必备知识
    Servlet3.0学习总结(一)——使用注解标注Servlet
    一张图讲清楚高可用、高性能、可扩展的WEB系统架构
  • 原文地址:https://www.cnblogs.com/ALANALLEN21LOVE28/p/11869508.html
Copyright © 2020-2023  润新知