[luoguP2219] [HAOI2007]修筑绿化带(单调队列)
需要n*m的算法,考虑单调队列
可以预处理出来
a[i][j]表示以i,j为右下角的绿化带+花坛的和
b[i][j]表示以i,j为右下角的花坛的和
那么我们可以单调队列跑出来在A-C-1,B-D-1的矩阵中的b[i][j]的最小值
枚举i,j,用取a[i][j]-ans[i-1][j-1]的最大值
#include <cstdio>
#include <iostream>
#define N 2001 using namespace std; int n, m, A, B, C, D, E, F, h, t, ans;
int a[N][N], b[N][N], c[N][N], ans1[N][N], ans2[N][N], q[N]; inline int read()
{
int x = 0, f = 1;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
return x * f;
} inline void work1(int k)
{
int i;
h = 1, t = 0;
for(i = D; i <= m; i++)
{
while(h <= t && b[k][q[t]] > b[k][i]) t--;
q[++t] = i;
while(h <= t && q[h] <= i - F) h++;
ans1[k][i] = b[k][q[h]];
}
} inline void work2(int k)
{
int i;
h = 1, t = 0;
for(i = C; i <= n; i++)
{
while(h <= t && ans1[q[t]][k] > ans1[i][k]) t--;
q[++t] = i;
while(h <= t && q[h] <= i - E) h++;
ans2[i][k] = ans1[q[h]][k];
}
} int main()
{
int i, j;
n = read();
m = read();
A = read();
B = read();
C = read();
D = read();
E = A - C - 1;
F = B - D - 1;
for(i = 1; i <= n; i++)
for(j = 1; j <= m; j++)
c[i][j] = read() + c[i][j - 1] + c[i - 1][j] - c[i - 1][j - 1];
for(i = 1; i <= n; i++)
for(j = 1; j <= m; j++)
{
if(i >= A && j >= B) a[i][j] = c[i][j] - c[i - A][j] - c[i][j - B] + c[i - A][j - B];
if(i >= C && j >= D) b[i][j] = c[i][j] - c[i - C][j] - c[i][j - D] + c[i - C][j - D];
}
for(i = C; i <= n; i++) work1(i);
for(i = D; i <= m; i++) work2(i);
for(i = A; i <= n; i++)
for(j = B; j <= m; j++)
ans = max(ans, a[i][j] - ans2[i - 1][j - 1]);
printf("%d\n", ans);
return 0;
}
[luoguP2219] [HAOI2007]修筑绿化带(单调队列)的更多相关文章
- 洛谷.2219.[HAOI2007]修筑绿化带(单调队列)
题目链接 洛谷 COGS.24 对于大的矩阵可以枚举:对于小的矩阵,需要在满足条件的区域求一个矩形和的最小值 预处理S2[i][j]表示以(i,j)为右下角的C\(*\)D的矩阵和, 然后对于求矩形区 ...
- luogu 2219[HAOI2007]修筑绿化带 单调队列
Code: #include<bits/stdc++.h> using namespace std; #define setIO(s) freopen(s".in",& ...
- P2219 [HAOI2007]修筑绿化带(单调队列)
P2219 [HAOI2007]修筑绿化带 二维单调队列 写了这题 P2216 [HAOI2007]理想的正方形 后,你发现可以搞个二维单调队列 来保存矩形(i+1,i+A-1)(j+1,j+B-1 ...
- 洛谷P2219 [HAOI2007]修筑绿化带(单调队列)
传送门 啧……明明以前做到过这种类型的题结果全忘了…… 这种矩阵的,一般都是先枚举行,然后对列进行一遍单调队列,搞出右下角在每一行中合法位置时的最小权值 再枚举列,对行做一遍单调队列,用之前搞出来的最 ...
- 洛谷2219:[HAOI2007]修筑绿化带——题解
https://www.luogu.org/problemnew/show/P2219#sub 为了增添公园的景致,现在需要在公园中修筑一个花坛,同时在画坛四周修建一片绿化带,让花坛被绿化带围起来. ...
- [HAOI2007] 修筑绿化带
类型:单调队列 传送门:>Here< 题意:给出一个$M*N$的矩阵,每一个代表这一格土地的肥沃程度.现在要求修建一个$C*D$的矩形花坛,矩形绿化带的面积为$A*B$,要求花坛被包裹在绿 ...
- luogu2219 [HAOI2007]修筑绿化带
和「理想的正方形」比较相似,需要先掌握那道题. 花坛外头每一边必须套上绿化带 #include <iostream> #include <cstdio> using names ...
- P2219 [HAOI2007]修筑绿化带
我是题面 这道题跟理想的正方形很像,不大明白蛤OI是怎么想的,一年出两道这么相近的题 这道题有两个矩形,所以就有了两种做法(说是两种做法,其实只是维护的矩形不同) 一种是维护大矩形,一种是维护小矩形, ...
- [HAOI2007]修筑绿化带 题解
题意分析 给出一个 $m*n$ 的矩阵 $A$ ,要求从中选出一个 $a*b$ 的矩阵 $B$ ,再从矩阵 $B$ 中选出一个 $c*d$ 的矩阵 $C$ ,要求矩阵 $B,C$ 的边界不能重合,求矩 ...
随机推荐
- 解决Unsupported major.minor version 51.0报错问题
问题产生原因:计算机环境变量的jdk版本与eclipse使用的jdk版本不一致 解决方法: 1.查看计算机环境变量的jdk版本 2.查看eclipse项目java compiler的方法:在项目点右键 ...
- IOS弹出视图preferredContentSize
UIViewController.preferredContentSize代理旧方法 contentSizeForViewInPopover. self.contentSizeForViewInPop ...
- COGS 1786. 韩信点兵
★★★ 输入文件:HanXin.in 输出文件:HanXin.out 简单对比时间限制:1 s 内存限制:256 MB [题目描述] 韩信是中国军事思想“谋战”派代表人物,被后人奉为“ ...
- 接口接收gzip压缩数据并解压
asp.net 接收前端gzip 压缩后的数据,接收端需要进行解压 public string GetResponseBody(HttpWebResponse response) { string r ...
- php 小坑记录
1 empty PHP<=5.5不能用于判断一个表达式的执行结果并且netbeans 和eclipse编辑器识别不出来此错误 含有此用法的 类 和页面将会报错 empty($this-> ...
- 系统报错undefine not symbol armv7
libz.dylib libsqlite3.dylib libstdc++.dylib 添加这些动态链接库
- 激励CEO们最好的办法就是鼓励他们不要停止思考
我们应该怎样在企业中释放出每一个人都可能内在的自我驱动力呢? 我创业十多年来,结识了很多创业家,他们中很多和我一样也试图通过学习实践找到有效管理的捷径,一个最简单的法则,最好还是比较容易的.事实上,最 ...
- python:lambda、filter、map、reduce
lambda 为关键字.filter,map,reduce为内置函数. lambda:实现python中单行最小函数. g = lambda x: x * 2 #相当于 def g(x): retur ...
- metasploit-shellcode生成
0x00 安装metasploit $ curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/t ...
- clover如何使用UEFI引导和EFI驱动选择
EFI分区实际上是一个FAT格式的分区,不一定要是第一个分区,GPT磁盘下任何一个FAT文件格式的分区都可以用来放EFI引导文件.主板UEFI先默认引导你所设置的第一优先启动分区下的\EFI\boot ...