修筑绿化带题解

修筑绿化带题解

我的做法实际上神奇且麻烦,大家其实可以看一下别人的做法。

这是一个单调队列优化DP题(废话)。

我的大概做法是:将每个c乘d的矩形化成一个点,将从a乘b的矩形中选一个c乘d的矩形转化为:在(a-c+1)*(b-d+1)的矩形中选一个值最小的点。

具体做法如下:

1.求出二维前缀和p,再求出以一个点为左上角的c乘d的矩形的值之和a。

2.求出每一以某点开始的长度为a-c+1的列的最小值sum。

3.剩下的就是在n-a+1行上,每一行求出长度为b-d+1的sum最小值(实际上就是每个a乘b的矩形中c乘d矩形的最小值),ans跟a乘b矩形权值和-最小值取max即可。

具体看代码吧:

#include<bits/stdc++.h>
using namespace std;
const int N=1006;
int n,m,t1,t2,t3,t4,t,head=1,tail=0,p[N][N],a[N][N],sum[N][N],q[N],ans=-1;
inline int read(){
   int T=0,F=1; char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-') F=-1; ch=getchar();}
   while(ch>='0'&&ch<='9') T=(T<<3)+(T<<1)+(ch-48),ch=getchar();
   return F*T;
}
int main(){
    n=read(),m=read(),t1=read(),t2=read(),t3=read(),t4=read();
    for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) p[i][j]=read(),p[i][j]=p[i-1][j]+p[i][j-1]-p[i-1][j-1]+p[i][j];
    for(int i=1;i<=n-t3+1;++i) for(int j=1;j<=m-t4+1;++j) a[i][j]=p[i+t3-1][j+t4-1]-p[i+t3-1][j-1]+p[i-1][j-1]-p[i-1][j+t4-1];
    for(int i=1;i<=m-t4+1;++i){
        tail=0,head=1;
        for(int j=2;j<=t1-t3;++j){
            while(tail&&a[q[tail]][i]>=a[j][i]) --tail;
            q[++tail]=j;
        }
        for(int j=1;j<=n-t1+1;++j){
            sum[j][i]=a[q[head]][i];
            while(q[head]<=j+1&&head<=tail) ++head;
            while(tail>=head&&a[q[tail]][i]>=a[j+t1-t3][i]) --tail;
            q[++tail]=j+t1-t3;
        }
    }
    for(int i=1;i<=n-t1+1;++i){
        head=1,tail=0;
        for(int j=2;j<=t2-t4;++j){
            while(tail&&sum[i][q[tail]]>=sum[i][j]) --tail;
            q[++tail]=j;
        }
        for(int j=1;j<=m-t2+1;++j){
            ans=max(ans,p[i-1][j-1]-p[i-1][j+t2-1]+p[i+t1-1][j+t2-1]-p[i+t1-1][j-1]-sum[i][q[head]]);
            while(q[head]<=j+1&&head<=tail) ++head;
            while(tail>=head&&sum[i][q[tail]]>=sum[i][j+t2-t4]) --tail;
            q[++tail]=j+t2-t4;
        }
    }
    printf("%d\n",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/ljk123-de-bo-ke/p/11478448.html

时间: 2024-11-13 04:04:02

修筑绿化带题解的相关文章

[题解] [HAOI2007] 修筑绿化带

题面 题解 题目意思比较简单, 就不在这里赘述了 本着练习平衡树的思路, 我把方法尝试往上面去套, 结果想不出 只能弃掉平衡树 最后想出来的方法是这样的 我们运用类似于高维前缀和那样一维一维加上去的方法 先横着统计在某个范围内和最小的 \(c * d\) 矩阵, 把贡献算在范围的右下角 注意, 这里保证了这个矩阵在以 \((i, j)\) 为右下角的某个范围之内 然后再竖着计算答案, 我们固定 \(a * b\) 矩形的右边在某一列, 就只用考虑行的变化了 从上往下依次枚举右下角, 每次弹出不合

P2219 [HAOI2007]修筑绿化带

题目描述 为了增添公园的景致,现在需要在公园中修筑一个花坛,同时在画坛四周修建一片绿化带,让花坛被绿化带围起来. 如果把公园看成一个M * N的矩形,那么花坛可以看成一个C * D的矩形,绿化带和花坛一起可以看成一个A * B的矩形. 如果将花园中的每一块土地的"肥沃度"定义为该块土地上每一个小块肥沃度之和,那么, 绿化带的肥沃度=A * B块的肥沃度-C * D块的肥沃度 为了使得绿化带的生长得旺盛,我们希望绿化带的肥沃度最大. 输入输出格式 输入格式: 第一行有6个正整数M,N,A

[HAOI2007] 修筑绿化带

类型:单调队列 传送门:>Here< 题意:给出一个$M*N$的矩阵,每一个代表这一格土地的肥沃程度.现在要求修建一个$C*D$的矩形花坛,矩形绿化带的面积为$A*B$,要求花坛被包裹在绿化带中,且不能碰到绿化带边缘.问绿化带的最大肥沃程度 解题思路 暴力做法:枚举绿化带,然后选出能使其肥沃程度最大的花坛位置. 很容易发现要使绿化带的肥沃程度最大,也就是让所选的花坛的肥沃程度尽量小.由此,问题转化为了求固定矩形内部规定大小的最小子矩形 为了表达方便,以下称绿化带为矩形$AB$,花坛为矩形$CD

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

题目链接 洛谷 COGS.24 对于大的矩阵可以枚举:对于小的矩阵,需要在满足条件的区域求一个矩形和的最小值 预处理S2[i][j]表示以(i,j)为右下角的C\(*\)D的矩阵和, 然后对于求矩形区域的最小值,可以先将每行看做一个数列,对于每个点y,得到一个[y-(B-3),y]的最小值 处理完行后得到Minr[][],对每列的进行同样的操作,就可以得到Min[x][y]表示([x-A+3,x],[y-B+3,y])的最小矩形和 但是注意单调队列处理的是S2,S2表示的是C\(*\)D的和,n

单调队列单调栈

单调队列单调栈 Tags:数据结构 更好阅读体验:https://www.zybuluo.com/xzyxzy/note/1041449 一.概述 单调队列单调栈是很基础的数据结构,常用来优化一些东西比如说优化DP 那么大概意思就是在栈或队列中按照某关键字单调维护信息,从而实现一些功能 其实很久之前接触过单调队列和单调栈,但一直没有刷题,趁这两天被LCT弄晕的时候复习下这些 先看题 二.题单 普及- [x] P1886 滑动窗口 https://www.luogu.org/problemnew/

题解 P1550 【[USACO08OCT]打井Watering Hole】

题面(翻译有点问题,最后一句话) 农民John 决定将水引入到他的n(1<=n<=300)个牧场.他准备通过挖若 干井,并在各块田中修筑水道来连通各块田地以供水.在第i 号田中挖一口井需要花费W_i(1<=W_i<=100,000)元.连接i 号田与j 号田需要P_ij (1 <= P_ij <= 100,000 , P_ji=P_ij)元. 请求出农民John 需要为使所有农场都与有水的农场相连或拥有水井所需要的钱数. 题意 有n个点,每个点之间都有边权,但是每个点也

洛谷 P1079 Vigen&#232;re 密码 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:https://www.luogu.org/problem/show?pid=1079 题目描述 16 世纪法国外交家 Blaise de Vigenère 设计了一种多表密码加密算法――Vigenère 密 码.Vigenère 密码的加密解密算法简单易用,且破译难度比较高,曾在美国南北战争中为 南军所广泛使用. 在密码学中,我们称需要加密的信息为明文,用 M 表示:称加密后的信息为密文,用 C 表示:而密钥是一种

8.8联考题解

今天的T1让我怀疑我是不是在做奥赛题--这考的是什么知识点啊这个,会不会用绝对值函数? Evensgn 的债务 时间限制: 1 Sec  内存限制: 128 MB 题目描述 Evensgn 有一群好朋友,他们经常互相借钱.假如说有三个好朋友A,B,C.A 欠 B 20 元,B 欠 C 20 元,总债务规模为 20+20=40 元.Evensgn 是个追求简约的人,他觉得这样的债务太繁杂了.他认为,上面的债务可以完全等价为 A 欠C20 元,B 既不欠别人,别人也不欠他.这样总债务规模就压缩到了 

POJ 2533 - Longest Ordered Subsequence(最长上升子序列) 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:http://poj.org/problem?id=2533 Description A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence of the given numeric sequence (a1, a2, ..., aN) be any sequence (ai1, ai2, ..., aiK)