测试链接

题面:

Farmer John is not good at multitasking. He gets distracted often, making it hard to complete long projects. Currently, he is trying to paint one side of his barn, but he keeps painting small rectangular areas and then getting sidetracked by the needs of tending to his cows, leaving some parts of the barn painted with more coats of paint than others.

We can describe the side of the barn as a 2D x–y plane, on which Farmer John paints N rectangles, each with sides parallel to the coordinate axes, each described by the coordinates of its lower-left and upper-right corner points.

Farmer John wants to apply several coats of paint to the barn so it doesn’t need to be repainted again in the immediate future. However, he doesn’t want to waste time applying an excessive number of coats of paint. It turns out that K coats of paint is the optimal amount. However, looking at the amount of area covered by K coats of paint, he is not very happy. He is willing to paint up to two additional rectangles to try and increase this area, as long as these two rectangles are disjoint (not sharing any positive amount of area in common). Note that he can also decide to paint zero new rectangles or just one new rectangle if this ends up being the best thing to do.

INPUT
The first line of input contains N and K (1≤K,N≤1e5). Each of the remaining N lines contains four integers x1,y1,x2,y2 describing a rectangular region being painted, with lower-left corner (x1,y1) and upper-right corner (x2,y2) . All x and y values are in the range 0…200 , and all rectangles have positive area.

Like the rectangles he already painted, any new rectangles that Farmer John paints must have positive area, and their corner points must have x and y coordinates in the range 0…200.

OUTPUT
Please output the maximum area of the barn that could be covered by exactly K coats of paint, if Farmer John paints up to two additional disjoint rectangles.

SAMPLE INPUT:
3 2
1 1 4 4
3 3 7 6
2 2 8 7
SAMPLE OUTPUT:
26

题意:

有一个200*200的矩形区域,在里面画n个矩形,最后可以额外任意画零个、一个或两个矩形(两个矩形时要保证两个矩形不相交),询问最后整个区域内正好被k个矩形覆盖的面积。

思路:

这题的简化版是最后没有额外矩阵,那么就只需要对每个要画的矩阵打一个二维差分的标记,然后用二维前缀和判断每个小块的值是否等于k,把等于k的块数统计下来就是答案。

这道题先和简化版的一样,先求出在不加额外矩阵的情况下的等于k的块数,然后把原来的图变一下,把等于k-1的变为1,把等于k的变为-1,其余的都为0。因为覆盖一个矩阵后,原来k-1的块就会变为k,会增加答案,而原来就是k的会变为k+1,就会减少答案,而其他的都不会都答案造成影响。现在的图中只有0,1,-1,求怎么样覆盖矩阵可以使答案最大就变成了在现在的图中如何选择举证可以使被选中区域的和最大。

先考虑一个简单问题,在一个一维的数组中求得最大的子区间和,显然可以dp[i]=max(dp[i-1]+num[i],num[i])这样扫一遍就可以了,复杂度只需要On。

如果是在二维中求最大子矩阵的和呢?可以先On^2枚举子矩阵的上边界和下边界,然后对于每一列,把上边界和下边界内的数值求和,这样二维就被压成了一维,然后用刚才的方法求出最大的子区间和,这个过程是在确定矩阵的左边界和右边界。当然求出的值还需要跟0取个max,因为可以不画额外的矩阵。因为可以画两个矩阵,观察两个矩阵的分布,发现只有两种情况,1.以一条竖线为界,一个在左,另一个在右。2.以一条水平线为界,一个在上,另一个在下。刚才把二维压缩成一维后需要做两次,一次从左往右,另一次从右往左。这里处理的是左右分布的情况,上下分布的相似的也需要处理。

最后原来求出的答案再加上子矩阵最大和便是答案。

复杂度On^3

参考代码:

#include<bits/stdc++.h>
using namespace std;int mp[205][205];//原图
int nmp[205][205];//新图
int sum1[205][205];//竖着的前缀和
int sum2[205][205];//横着的前缀和
int dp[205];//临时的dp数组
int li[205],ri[205],up[205],dw[205];//分别记录从最左到位置x的最大子矩阵和,最右...,最上...,最下int main(){int n,k;scanf("%d%d",&n,&k);int x1,y1,x2,y2;for(int i=1;i<=n;i++){scanf("%d%d%d%d",&x1,&y1,&x2,&y2);x1++,y1++,x2++,y2++;//坐标整体加1,为了前缀和写的方便一点mp[x1][y1]++;mp[x1][y2]--;mp[x2][y1]--;mp[x2][y2]++;}int cnt=0;for(int i=1;i<=200;i++){for(int j=1;j<=200;j++){mp[i][j]+=mp[i][j-1]+mp[i-1][j]-mp[i-1][j-1];if(mp[i][j]==k){nmp[i][j]=-1;cnt++;//统计原来答案}else if(mp[i][j]==k-1){nmp[i][j]=1;}}}//printf("%d\n",cnt);//分别作竖着的和横着的前缀和for(int j=1;j<=200;j++){for(int i=1;i<=200;i++){sum1[i][j]=sum1[i-1][j]+nmp[i][j];}}for(int i=1;i<=200;i++){for(int j=1;j<=200;j++){sum2[i][j]=sum2[i][j-1]+nmp[i][j];}}int ans=0;memset(dp,0,sizeof(dp));for(int i=1;i<=200;i++){for(int j=i;j<=200;j++){//前两层枚举上下边界for(int k=1;k<=200;k++){//枚举列坐标int tmp=sum1[j][k]-sum1[i-1][k];//利用前缀和压缩成一维dp[k]=max(0,max(tmp,dp[k-1]+tmp));li[k]=max(li[k],dp[k]);}}}memset(dp,0,sizeof(dp));for(int i=1;i<=200;i++){for(int j=i;j<=200;j++){for(int k=200;k>=1;k--){int tmp=sum1[j][k]-sum1[i-1][k];dp[k]=max(0,max(tmp,dp[k+1]+tmp));ri[k]=max(ri[k],dp[k]);}}}memset(dp,0,sizeof(dp));for(int i=1;i<=200;i++){for(int j=i;j<=200;j++){for(int k=1;k<=200;k++){int tmp=sum2[k][j]-sum2[k][i-1];dp[k]=max(0,max(tmp,dp[k-1]+tmp));up[k]=max(up[k],dp[k]);}}}memset(dp,0,sizeof(dp));for(int i=1;i<=200;i++){for(int j=i;j<=200;j++){for(int k=200;k>=1;k--){int tmp=sum2[k][j]-sum2[k][i-1];dp[k]=max(0,max(tmp,dp[k+1]+tmp));dw[k]=max(dw[k],dp[k]);}}}//作前缀最大值for(int i=1;i<=200;i++){li[i]=max(li[i],li[i-1]);up[i]=max(up[i],up[i-1]);}for(int i=200;i>=1;i--){ri[i]=max(ri[i],ri[i+1]);dw[i]=max(dw[i],dw[i+1]);}//枚举分界线统计答案for(int i=1;i<=200;i++){ans=max(ans,li[i]+ri[i+1]);ans=max(ans,up[i]+dw[i+1]);}//printf("%d\n",ans);printf("%d\n",cnt+ans);return 0;
}

Painting the Barn 2 (最大子矩阵)相关推荐

  1. luoguP2701 [USACO5.3]巨大的牛棚Big Barn(极大子矩阵)

    题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N x N 的方格.输入数据中包括有树的 ...

  2. [洛谷 P4084 USACO17DEC] Barn Painting G (树形dp经典)

    [洛谷 P4084 USACO17DEC] Barn Painting G 题目链接 大致题意: 给定一颗N个节点组成的树,3种颜色,其中K个节点已染色,要求任意两相邻节点颜色不同,求合法染色方案数 ...

  3. 洛谷P4084 [USACO17DEC]Barn Painting G 题解

    洛谷P4084 [USACO17DEC]Barn Painting G 题解 题目链接:P4084 [USACO17DEC]Barn Painting G 题意:题意:给定一颗N个节点组成的树,3种颜 ...

  4. P4084 [USACO17DEC]Barn Painting

    题意翻译 题意:给定一颗N个节点组成的树,3种颜色,其中K个节点已染色,要求任意两相邻节点颜色不同,求合法染色方案数. 翻译贡献者:Il_ItzABC_lI 题目描述 Farmer John has ...

  5. 【洛谷P4084】Barn Painting【树形DP】

    题目大意: 题目链接:https://www.luogu.org/problemnew/show/P4084 一棵nnn个节点的树上有kkk个点已被染色.求将这棵树染成三种颜色且相邻的节点颜色不同的方 ...

  6. [bzoj1582][Usaco2009 Hol]Holiday Painting 节日画画_线段树

    Holiday Painting 节日画画 bzoj-1582 Usaco-2009 Hol 题目大意:给定两个n*m的01网格图.q次操作,每次将第二个网格图的子矩阵全部变成0或1,问每一次操作后两 ...

  7. 矩阵hash + KMP - UVA 12886 The Big Painting

    The Big Painting Problem's Link:  http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=88791 ...

  8. 概念艺术绘画学习教程 Schoolism – Foolproof Concept Painting with Airi Pan

    Schoolism--万无一失的概念绘画潘 大小解压后:3.19G 含课程素材文件 1920X1080 .mp4 语言:英语+中英文字幕(根据原英文字幕机译更准确) 信息: 万无一失的概念绘画潘 本课 ...

  9. 求一个矩阵的最大子矩阵

    #include <iostream> #include <string> #include <assert.h> #include <malloc.h> ...

最新文章

  1. 我已经喜欢上了Python
  2. 万万没想到,一个可执行文件原来包含了这么多信息!
  3. C#基础之如何判断两个文件内容是否相同
  4. 提防Java中的函数式编程!
  5. fatfs 文件属性_FATFS文件系统剖析(全).
  6. linux 反汇编 静态库,如何反汇编.lib静态库?
  7. Mysql入门实战上
  8. dnf 卸载软件linux,Linux软件安装与卸载的基本概念
  9. Fiji/ImageJ调整图像的对比度;Fiji/Image查看图像的像素直方图分布
  10. ctfshow 8神PNG隐写入门(土)赛 WP
  11. 四旋翼飞行器避障系统基础
  12. 考研日语线上笔记(五):中级日语语法总结20课(11~20)
  13. 力扣题解:面试题 02.03. 删除中间节点
  14. InstallShield打包
  15. R语言使用qcauchy函数生成柯西分布分位数函数数据、使用plot函数可视化柯西分布分位数函数数据(Cauchy distribution)
  16. ffmpeg安装及在java中的使用案例
  17. ASR语音转文字模型——项目落地
  18. 将腾讯qlv格式的视频转换为mp4格式
  19. Alpine安装与使用
  20. 产品经理必须要了解的26个文档

热门文章

  1. 华为p30鸿蒙发布会,华为P30 Pro发布会回顾重写摄影规则 华为P30系列发布会直播-中关村在线...
  2. python特性无需修改_python – 2to3说“不需要更改”,然后是“需要修改的文件”...
  3. 面向对象 抽象类与接口类
  4. mysql8版本升级(无损升级)8.0.20升级到8.0.21
  5. 预训练模型mlm阅读理解任务
  6. c语言 读入两个数组,c语言:读入两个学生的情况存入结构数组。
  7. 什么是标记化?令牌?
  8. 炫酷JavaScript转盘时钟动态js特效
  9. 51nod 1417 天堂里的游戏
  10. 黑马程序员-----Java基础-----正则表达式