[HAOI2007] 修筑绿化带
类型:单调队列
传送门:>Here<
题意:给出一个$M*N$的矩阵,每一个代表这一格土地的肥沃程度。现在要求修建一个$C*D$的矩形花坛,矩形绿化带的面积为$A*B$,要求花坛被包裹在绿化带中,且不能碰到绿化带边缘。问绿化带的最大肥沃程度
解题思路
暴力做法:枚举绿化带,然后选出能使其肥沃程度最大的花坛位置。
很容易发现要使绿化带的肥沃程度最大,也就是让所选的花坛的肥沃程度尽量小。由此,问题转化为了求固定矩形内部规定大小的最小子矩形
为了表达方便,以下称绿化带为矩形$AB$,花坛为矩形$CD$。
为了计算方便,我们可以先预处理出以$(i,j)$为右下角的矩形$AB$和矩形$CD$的肥沃程度。利用前缀和处理即可
显然固定矩形$AB$以后,矩形$CD$的可取范围也被固定了。这个范围是可以计算的。设矩形$AB$的右下角为$(i+1,j+1)$,则矩形$CD$的右下角可取范围是$(i+1-(A-1)+C \rightarrow i, j+1-(B-1)+D \rightarrow j)$。也就是$$(i-A+C+2 \rightarrow i, j-B+D+2 \rightarrow j)$$由于我们已经计算出了以$(i,j)$为右下角的矩形$CD$的肥沃程度,因此我们可以把每一个格子看做是一个矩形$CD$。于是要求以同一个$i$作为右下角横坐标的矩形时,他们就是一个横行里的格子。用一个单调队列就很容易求出
求出范围内每一个横行的最小值以后,对所有这些最小值再竖着用单调队列求一个最小值。即可以得出整个范围内的最小值。问题就解决了
这题的代码实现也很难(本蒟蒻打了2.5h+),由于边界条件如此的坑而且样例又如此的水,不得不自己造了好几组数据一个一个调……关键在于把控清楚每一个数组表示的具体内容,包括要不要$+1或-1$
Code
/*By DennyQi 2018.8.19*/
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
#define r read()
#define Max(a,b) (((a)>(b)) ? (a) : (b))
#define Min(a,b) (((a)<(b)) ? (a) : (b))
using namespace std;
typedef long long ll;
const int MAXN = ;
const int INF = ;
inline int read(){
int x = ; int w = ; register int c = getchar();
while(c ^ '-' && (c < '' || c > '')) c = getchar();
if(c == '-') w = -, c = getchar();
while(c >= '' && c <= '') x = (x<<) + (x<<) + c - '', c = getchar();
return x * w;
}
int M,N,A,B,C,D,h,t;
int a[MAXN][MAXN],sum[MAXN][MAXN],ab[MAXN][MAXN],cd[MAXN][MAXN];
int q[MAXN],mcd[MAXN][MAXN],mx[MAXN][MAXN];
int main(){
N = r, M = r;
A = r, B = r, C = r, D = r;
for(int i = ; i <= N; ++i){
h = , t = ;
for(int j = ; j <= M; ++j){
a[i][j] = r;
sum[i][j] = sum[i-][j] + sum[i][j-] - sum[i-][j-] + a[i][j];
ab[i][j] = sum[i][j] - sum[i][j-B] - sum[i-A][j] + sum[i-A][j-B];
cd[i][j] = sum[i][j] - sum[i][j-D] - sum[i-C][j] + sum[i-C][j-D];
if(i > C && j > D && i < N && j < M){
while(h <= t && cd[i][q[t]] >= cd[i][j]) --t;
q[++t] = j;
if(j - B + D + > ){
while(h <= t && q[h] < j - B + D + ) ++h;
}
if(i > C && j > D) mcd[i][j] = cd[i][q[h]];
}
}
}
for(int k = B; k <= M; ++k){
h = , t = ;
q[] = ;
for(int i = C+; i <= N; ++i){
while(h <= t && q[h] < i - A + C + ) ++h;
if(i >= A) mx[i][k] = mcd[q[h]][k-];
while(h <= t && mcd[q[t]][k-] >= mcd[i][k-]) --t;
q[++t] = i;
}
}
int ans = ;
for(int i = A; i <= N; ++i){
for(int j = B; j <= M; ++j){
ans = Max(ans, ab[i][j] - mx[i][j]);
}
}
printf("%d", ans);
return ;
}
[HAOI2007] 修筑绿化带的更多相关文章
- P2219 [HAOI2007]修筑绿化带(单调队列)
P2219 [HAOI2007]修筑绿化带 二维单调队列 写了这题 P2216 [HAOI2007]理想的正方形 后,你发现可以搞个二维单调队列 来保存矩形(i+1,i+A-1)(j+1,j+B-1 ...
- 洛谷2219:[HAOI2007]修筑绿化带——题解
https://www.luogu.org/problemnew/show/P2219#sub 为了增添公园的景致,现在需要在公园中修筑一个花坛,同时在画坛四周修建一片绿化带,让花坛被绿化带围起来. ...
- luogu2219 [HAOI2007]修筑绿化带
和「理想的正方形」比较相似,需要先掌握那道题. 花坛外头每一边必须套上绿化带 #include <iostream> #include <cstdio> using names ...
- [luoguP2219] [HAOI2007]修筑绿化带(单调队列)
传送门 需要n*m的算法,考虑单调队列 可以预处理出来 a[i][j]表示以i,j为右下角的绿化带+花坛的和 b[i][j]表示以i,j为右下角的花坛的和 那么我们可以单调队列跑出来在A-C-1,B- ...
- 洛谷.2219.[HAOI2007]修筑绿化带(单调队列)
题目链接 洛谷 COGS.24 对于大的矩阵可以枚举:对于小的矩阵,需要在满足条件的区域求一个矩形和的最小值 预处理S2[i][j]表示以(i,j)为右下角的C\(*\)D的矩阵和, 然后对于求矩形区 ...
- P2219 [HAOI2007]修筑绿化带
我是题面 这道题跟理想的正方形很像,不大明白蛤OI是怎么想的,一年出两道这么相近的题 这道题有两个矩形,所以就有了两种做法(说是两种做法,其实只是维护的矩形不同) 一种是维护大矩形,一种是维护小矩形, ...
- 洛谷P2219 [HAOI2007]修筑绿化带(单调队列)
传送门 啧……明明以前做到过这种类型的题结果全忘了…… 这种矩阵的,一般都是先枚举行,然后对列进行一遍单调队列,搞出右下角在每一行中合法位置时的最小权值 再枚举列,对行做一遍单调队列,用之前搞出来的最 ...
- luogu 2219[HAOI2007]修筑绿化带 单调队列
Code: #include<bits/stdc++.h> using namespace std; #define setIO(s) freopen(s".in",& ...
- [HAOI2007]修筑绿化带 题解
题意分析 给出一个 $m*n$ 的矩阵 $A$ ,要求从中选出一个 $a*b$ 的矩阵 $B$ ,再从矩阵 $B$ 中选出一个 $c*d$ 的矩阵 $C$ ,要求矩阵 $B,C$ 的边界不能重合,求矩 ...
随机推荐
- DSL 系列(2) - 插件的论述与实现
前言 本文主要探讨基于 DSL(domain specific language) 之上的插件设计,他们是领域的附属,为领域提供额外的服务,但领域不依赖于他们. 1. 论述 领域应当尽可能地去专注他的 ...
- NLP是什么
NLP是什么 而在计算机领域, NLP(Natural Language Processing),也就是人们常说的「自然语言处理」,就是研究如何让计算机读懂人类语言. 这包括,既要能让计算机理解自然语 ...
- [LeetCode] 56 - Merge Intervals 合并区间
Given a collection of intervals, merge all overlapping intervals. For example,Given [1,3],[2,6],[8,1 ...
- HDU 3478 Catch (连通性&&二分图判断)
链接 [https://vjudge.net/contest/281085#problem/C] 题意 一个n个点,m条边的图,开始的点是s 每次必须移动到相邻的位置,问你是否存在某个时刻所有点都可能 ...
- 如何让vba与java的TripleDES算法通用
本文链接:http://www.cnblogs.com/Charltsing/p/TripleDES.html 众所周知,java默认采用的TripleDES算法是ECB+PKCS#5填充方式.网上可 ...
- Python classmethod 修饰符
描述 classmethod修饰符对应的函数不需要实例化,不需要self参数,但第一个参数需要是表示自身类的cls参数,可以调用类的属性,类的方法,实例化对象等. 语法 classmethod语法: ...
- 生成短链接的URL
假设你想做一个像微博短链接那样的短链接服务,短链接服务生成的URL都非常短例如: http://t.cn/E70Piib, 我们应该都能想到链接中的E70Piib对应的就是存储长链接地址的数据记录的I ...
- noode inquirer
一. 由于交互的问题种类不同,inquirer为每个问题提供很多参数: type:表示提问的类型,包括:input, confirm, list, rawlist, expand, checkbox, ...
- react 路由 react-router-dom
import React from 'react'; import DataList from './data' import Tr from './Tr' // import One from '. ...
- [转帖]Linux分页机制之分页机制的演变--Linux内存管理(七)
Linux分页机制之分页机制的演变--Linux内存管理(七) 2016年09月01日 20:01:31 JeanCheng 阅读数:4543 https://blog.csdn.net/gatiem ...