题目里给的范围是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=;
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[];int cnt=;
int work(int l,int r,int seq[]){
int minx=0x7f7f7f7f,miny=0x7f7f7f7f,maxx=,maxy=;
for(int i=l;i<=r;++i){//printf("seq%d\n",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[][];int tot=;
int dfs(int l,int r,int k,int seq[]){//printf("%d\n",k);
if(k==){
int tmp=work(l,r,seq);
cnt--;
return tmp;
}else{
int ans=0x7f7f7f7f;
sort(seq+l,seq+r+,cmp1);
for(int i=l;i<r;++i){
for(int j=;j<k;++j){
++tot;
memcpy(s[tot],seq,sizeof(int)*);
++tot;
memcpy(s[tot],seq,sizeof(int)*);
if(x[seq[i]]!=x[seq[i+]]){
int tmp=dfs(l,i,j,s[tot-])+dfs(i+,r,k-j,s[tot]);
ans=min(ans,tmp);
}
--tot;--tot;
//printf("---------------\n");
}
}//printf("%d\n",ans);
sort(seq+l,seq+r+,cmp2);
for(int i=l;i<r;++i){
for(int j=;j<k;++j){
++tot;
memcpy(s[tot],seq,sizeof(int)*);
++tot;
memcpy(s[tot],seq,sizeof(int)*);
if(y[seq[i]]!=y[seq[i+]]){
int tmp=dfs(l,i,j,s[tot-])+dfs(i+,r,k-j,s[tot]);
ans=min(ans,tmp);
}
--tot;--tot;
//printf("---------------\n");
}
}//printf("%d\n",ans);
return ans;
}
}
int main(){
int n,k;
scanf("%d%d",&n,&k);
for(int i=;i<=n;++i){
scanf("%d%d",x+i,y+i);
}
for(int i=;i<=n;++i){
seq[i]=i;
}
printf("%d\n",dfs(,n,k,seq));
return ;
}

COGS103&tyvj1899 [NOIP2002]矩形覆盖的更多相关文章

  1. [LuoguP1034][Noip2002] 矩形覆盖

    [LuoguP1034][Noip2002] 矩形覆盖(Link) 在平面上有\(N\)个点,\(N\)不超过五十, 要求将这\(N\)个点用\(K\)个矩形覆盖,\(k\)不超过\(4\),要求最小 ...

  2. NOIP2002矩形覆盖[几何DFS]

    题目描述 在平面上有 n 个点(n <= 50),每个点用一对整数坐标表示.例如:当 n=4 时,4个点的坐标分另为:p1(1,1),p2(2,2),p3(3,6),P4(0,7),见图一. 这 ...

  3. NOIP2002 矩形覆盖

    题四 矩形覆盖(存盘名NOIPG4) [问题描述]: 在平面上有 n 个点(n <= 50),每个点用一对整数坐标表示.例如:当 n=4 时,4个点的坐标分另为:p1(1,1),p2(2,2), ...

  4. 洛谷1034 NOIP2002 矩形覆盖

    问题描述 在平面上有 n 个点(n <= 50),每个点用一对整数坐标表示.例如:当 n=4 时,4个点的坐标分另为:p1(1,1),p2(2,2),p3(3,6),P4(0,7). 这些点可以 ...

  5. 【OpenJudge 1793】矩形覆盖

    http://noi.openjudge.cn/ch0405/1793/ 好虐的一道题啊. 看数据范围,一眼状压,然后调了好长时间QwQ 很容易想到覆盖的点数作为状态,我用状态i表示至少覆盖状态i表示 ...

  6. bzoj 1185 旋转卡壳 最小矩形覆盖

    题目大意 就是求一个最小矩形覆盖,逆时针输出其上面的点 这里可以看出,那个最小的矩形覆盖必然有一条边经过其中凸包上的两个点,另外三条边必然至少经过其中一个点,而这样的每一个点逆时针走一遍都满足单调性 ...

  7. [剑指OFFER] 斐波那契数列- 跳台阶 变态跳台阶 矩形覆盖

    跳台阶 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法. class Solution { public: int jumpFloor(int number) ...

  8. UVA-11983-Weird Advertisement(线段树+扫描线)[求矩形覆盖K次以上的面积]

    题意: 求矩形覆盖K次以上的面积 分析: k很小,可以开K颗线段树,用sum[rt][i]来保存覆盖i次的区间和,K次以上全算K次 // File Name: 11983.cpp // Author: ...

  9. 【旋转卡壳+凸包】BZOJ1185:[HNOI2007]最小矩形覆盖

    1185: [HNOI2007]最小矩形覆盖 Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 1945  Solve ...

随机推荐

  1. codevs2010 求后序遍历

    难度等级:白银 2010 求后序遍历 题目描述 Description 输入一棵二叉树的先序和中序遍历序列,输出其后序遍历序列. 输入描述 Input Description 共两行,第一行一个字符串 ...

  2. C#字符串默认值

    using System; class MYTestX { class CT { } class CO { public CT ott; //默认是null public string strx;// ...

  3. Hadoop: MapReduce2多个job串行处理

    复杂的MapReduce处理中,往往需要将复杂的处理过程,分解成多个简单的Job来执行,第1个Job的输出做为第2个Job的输入,相互之间有一定依赖关系.以上一篇中的求平均数为例,可以分解成三个步骤: ...

  4. 获取图片base64编码的几种方法

    前文中我们聊了 Data URI 和 base64编码,稍微回顾下.base64编码 是将数据用 64 个可打印的字符进行编码的方式,任何数据底层实现都是二进制,所以都可以进行 base64编码,ba ...

  5. 如何用 fiddler 代理调试本地手机页面

    最近在做移动端的页面,但是移动端的调试很蛋疼.虽然说 90% 的功能都能用 chrome 下的模拟器来模拟解决,但是剩余的 10% 却只能在真机上调试.比如说一两个像素的误差,比如说只有真机上才能重现 ...

  6. 各种主流 SQLServer 迁移到 MySQL 工具对比

          我之所以会写这篇对比文章,是因为公司新产品研发真实经历过这个痛苦过程(传统基于SQL Server开发的C/S产品转为MySQL云产品).首次需要数据转换是测试环节,当时为了快速验证新研发 ...

  7. GitHub: Windows 下的简单使用

    这段时间在博客园多了很多关于GitHub的文章,但是我的确没怎么看懂.不过这几天简单的看了写资料,亲身操作之后也有了一点体会.这算是最简单的GitHub入门了吧,基本全是鼠标操作.这也是这几天的总结, ...

  8. HashSet<T>类 用法

    HashSet<T>类主要是设计用来做高性能集运算的,例如对两个集合求交集.并集.差集等.集合中包含一组不重复出现且无特性顺序的元素 改变集的值的方法: HashSet<T>的 ...

  9. SQL Server output子句用法 output inserted.id 获取刚插入数据的id

    --插入数据,并返回刚刚插入的数据id INSERT INTO [soloreztest] ([name]) output inserted.id VALUES ('solorez') --执行结果: ...

  10. yii2干货

    Sites 网站 yiifeed:Yii 最新动态都在这里 yiigist:Yii 专用的 Packages my-yii:Yii 学习资料和新闻 Docs 文档 Yii Framework 2.0 ...