题意分析

给出一个 $m*n$ 的矩阵 $A$ ,要求从中选出一个 $a*b$ 的矩阵 $B$ ,再从矩阵 $B$ 中选出一个 $c*d$ 的矩阵 $C$ ,要求矩阵 $B,C$ 的边界不能重合,求矩阵 $C$ 在矩阵 $B$ 中的补集的权值和的最大值。

思路分析

通过分析题目后可以发现本题可以用二维单调队列进行求解,同时利用到了二维前缀和。即先对其中一维进行求解,然后再求解另一维。

具体实现

1. 预处理二维前缀和

设 $suml_{i,j}$ 表示以 $(i,j)$ 为右下角的矩形 $B$ 的权值和, $sums_{i,j}$ 表示以 $(i,j)$ 为右下角的矩形 $C$ 的权值和,$sum_{i,j}$ 表示 $(i,j)$ 的二维前缀和。递推式显然,就不赘述了。

2. 利用单调队列求解列的答案

设 $f1_{i,j}$ 表示以 $(i,j-b+d+1\sim j-1)$ 为右下角的矩阵 $C$ 中权值和的最大的矩阵,则对于每个 $j$ ,有:

  • 从队头排除过时决策
  • 若能构成矩阵 $B$ ,即 $j\geq b$,则队头为当前答案
  • 从队尾排除无用决策
  • 从队尾插入当前决策

3. 利用单调队列求解列的答案

设 $f2_{i,j}$ 表示以 $(i-a+c+1\sim i,j-b+d+1\sim j-1)$ 为右下角的矩阵 $C$ 中权值和的最大的矩阵,求解过程与上步类似,就不赘述了。

4. 遍历一遍找出答案

此时 $suml_{i,j}-f2_{i,j}$ 就是以 $(i,j)$ 为右下角的矩阵 $B$ 的答案,遍历所有矩阵 $B$ ,找出最大值即可。

有一个需要注意的点,矩阵 $B,C$ 的边界不能重合,在递推的时候下标需要注意。举例:$(c,d)$ 不能作为决策和答案,$(c+1,d+1)$ 只能作为决策而不能作为答案。

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
const int N=1100;
int m,n,a,b,c,d,ans;
int s[N][N],sum[N][N],suml[N][N],sums[N][N],f1[N][N],f2[N][N];
deque<int> q;
int main()
{
scanf("%d%d%d%d%d%d",&m,&n,&a,&b,&c,&d);
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
scanf("%d",&s[i][j]),sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+s[i][j];//递推二维前缀和
for(int i=a;i<=m;i++)
for(int j=b;j<=n;j++)
suml[i][j]=sum[i][j]-sum[i-a][j]-sum[i][j-b]+sum[i-a][j-b];
for(int i=c+1;i<=m;i++)
for(int j=d+1;j<=n;j++)
sums[i][j]=sum[i][j]-sum[i-c][j]-sum[i][j-d]+sum[i-c][j-d];//预处理
for(int i=c+1;i<=m;i++)
{
q.clear();q.push_back(d+1);
for(int j=d+2;j<=n;j++)
{
while(q.size() && q.front()<j-b+d+1)
q.pop_front();
if(j>=b)
f1[i][j]=sums[i][q.front()];
while(q.size() && sums[i][q.back()]>=sums[i][j])
q.pop_back();
q.push_back(j);
}
}//求解第一维
for(int j=b;j<=n;j++)
{
q.clear();q.push_back(c+1);
for(int i=c+2;i<=m;i++)
{
while(q.size() && q.front()<i-a+c+1)
q.pop_front();
if(i>=a)
f2[i][j]=f1[q.front()][j];
while(q.size() && f1[q.back()][j]>=f1[i][j])
q.pop_back();
q.push_back(i);
}
}//求解第二维
for(int i=a;i<=m;i++)
for(int j=b;j<=n;j++)
ans=max(ans,suml[i][j]-f2[i][j]); //找出答案
printf("%d",ans);
return 0;
}

[HAOI2007]修筑绿化带 题解的更多相关文章

  1. 洛谷2219:[HAOI2007]修筑绿化带——题解

    https://www.luogu.org/problemnew/show/P2219#sub 为了增添公园的景致,现在需要在公园中修筑一个花坛,同时在画坛四周修建一片绿化带,让花坛被绿化带围起来. ...

  2. P2219 [HAOI2007]修筑绿化带(单调队列)

    P2219 [HAOI2007]修筑绿化带 二维单调队列 写了这题 P2216 [HAOI2007]理想的正方形  后,你发现可以搞个二维单调队列 来保存矩形(i+1,i+A-1)(j+1,j+B-1 ...

  3. [HAOI2007] 修筑绿化带

    类型:单调队列 传送门:>Here< 题意:给出一个$M*N$的矩阵,每一个代表这一格土地的肥沃程度.现在要求修建一个$C*D$的矩形花坛,矩形绿化带的面积为$A*B$,要求花坛被包裹在绿 ...

  4. luogu2219 [HAOI2007]修筑绿化带

    和「理想的正方形」比较相似,需要先掌握那道题. 花坛外头每一边必须套上绿化带 #include <iostream> #include <cstdio> using names ...

  5. [luoguP2219] [HAOI2007]修筑绿化带(单调队列)

    传送门 需要n*m的算法,考虑单调队列 可以预处理出来 a[i][j]表示以i,j为右下角的绿化带+花坛的和 b[i][j]表示以i,j为右下角的花坛的和 那么我们可以单调队列跑出来在A-C-1,B- ...

  6. 洛谷.2219.[HAOI2007]修筑绿化带(单调队列)

    题目链接 洛谷 COGS.24 对于大的矩阵可以枚举:对于小的矩阵,需要在满足条件的区域求一个矩形和的最小值 预处理S2[i][j]表示以(i,j)为右下角的C\(*\)D的矩阵和, 然后对于求矩形区 ...

  7. P2219 [HAOI2007]修筑绿化带

    我是题面 这道题跟理想的正方形很像,不大明白蛤OI是怎么想的,一年出两道这么相近的题 这道题有两个矩形,所以就有了两种做法(说是两种做法,其实只是维护的矩形不同) 一种是维护大矩形,一种是维护小矩形, ...

  8. 洛谷P2219 [HAOI2007]修筑绿化带(单调队列)

    传送门 啧……明明以前做到过这种类型的题结果全忘了…… 这种矩阵的,一般都是先枚举行,然后对列进行一遍单调队列,搞出右下角在每一行中合法位置时的最小权值 再枚举列,对行做一遍单调队列,用之前搞出来的最 ...

  9. luogu 2219[HAOI2007]修筑绿化带 单调队列

    Code: #include<bits/stdc++.h> using namespace std; #define setIO(s) freopen(s".in",& ...

随机推荐

  1. PDO::quote

    PDO::quote — 为SQL语句中的字符串添加引号.(PHP 5 >= 5.1.0, PECL pdo >= 0.2.1) 说明 语法 public string PDO::quot ...

  2. PHP simplexml_load_string() 函数

    实例 转换形式良好的 XML 字符串为 SimpleXMLElement 对象,然后输出对象的键和元素: <?php$note=<<<XML<note>高佣联盟 w ...

  3. luogu 3188 [HNOI2007]梦幻岛宝珠

    LINK:梦幻岛宝珠 时隔多日 我再次挑战这道题.还是以失败告终. 我觉得这一道背包真的有点难度 这是一个数量较少 但是价值和体积较大的背包. 通常的01背包 要不就是体积小 要么是价值小 但这道题给 ...

  4. layui在odoo12上的应用,用widget覆盖原字段视图

    layui是一个前端框架,提供了许多前端的组件等,layui的详情自己官网地址:https://www.layui.com/doc/去查看 下面说一下最近用layui遇到的问题和解决方式: 问题:近期 ...

  5. 基于.NetCore3.1系列 —— 日志记录之日志配置揭秘

    一.前言 在项目的开发维护阶段,有时候我们关注的问题不仅仅在于功能的实现,甚至需要关注系统发布上线后遇到的问题能否及时的查找并解决.所以我们需要有一个好的解决方案来及时的定位错误的根源并做出正确及时的 ...

  6. 《国际化Web项目测试:记第一次兼职测试的经历(一)》

    疫情期间我一直在家远程办公,无意间接到了个做测试兼职的机会.在不耽搁本职工作的情况下,我从今年五月份开启了主职和副职的并行的状态.这种项目经历对于我来说算是一次全新的体验,当然也真是累的够呛.到目前为 ...

  7. 【NOIP2013】火柴排队 题解(贪心+归并排序)

    前言:一道水题. ----------------------- 题目链接 题目大意:给出数列$a_i$和$b_i$,问使$\sum_{i=1}^n (a_i-b_i)^2$最小的最少操作次数. 首先 ...

  8. JConsole、VisualVM 依赖的 JMX 技术到底是什么

    我是风筝,公众号「古时的风筝」,一个兼具深度与广度的程序员鼓励师,一个本打算写诗却写起了代码的田园码农! 文章会收录在 JavaNewBee 中,更有 Java 后端知识图谱,从小白到大牛要走的路都在 ...

  9. JAVA的基本程序设计结构(下)

    字符串 Java没有内置的字符串类型,而是在标准Java类库中提供了一个预定义类,叫做 String. String e=""; //an empty String String ...

  10. 漫画 | 到底是什么让IT人如此苦逼???

    写在最后 漫画是有点夸张,不过多少还是有点现实开发过程的影子! 老板很乐观,核心就是三个月上线,至于怎么办那是底下人的事. 产品很无奈,心里盘算着,万万不可在他这一环节耽误了进度,时间这么赶,先出个壳 ...