单调栈和队列讲解:传送门 HDU -1506题意: 就是给你一些矩形的高度,让你统计由这些矩形构成的那个矩形面积最大 如上图所示,如果题目给出的全部是递增的,那么就可以用贪心来解决 从左向右依次让每一个矩形的高度当作最后的高度,来从中选取最大值就可以了 但是如果它不是递增的,中间会出现低谷,那么要还想运用贪心策略就要把之前高度大于它的全部扔掉,但是再扔掉他们之前还要判断一下以他们为最后答案的高度可不可行,这样我们就是在构造一个递增序列,可以用栈来维护它 代码: 1 #include<stdio.…
前置问题:51nod 1102 面积最大的矩形 附上链接: 51nod 1102 面积最大的矩形 这题的题解博客 需要了解的知识:单调栈,在前置问题中已经讲解. 解题思路 对每行求左边连续1的个数,得到数组a[i][j]; 对于第j列,找出每个位置i的数字a[i][j]上面第一个比它小数字l,和下面第一个比它小的数字r. 由这个点所在列为底,这个点的数字为最小值产生的矩形的面积为a[i][j]*(r-l-1),用这一列每一个面积更新ans. 上面2的求法就是单调栈了,总时间复杂度o(n*m).…
题目链接:51nod 1158 全是1的最大子矩阵 题目分类是单调栈,我这里直接用与解最大子矩阵类似的办法水过了... #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define CLR(a,b) memset((a),(b),sizeof((a))) using namespace std; ; const int inf = 0x3f3f3f3f; int…
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1158 1158 全是1的最大子矩阵  基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题  收藏  关注 给出1个M*N的矩阵M1,里面的元素只有0或1,找出M1的一个子矩阵M2,M2中的元素只有1,并且M2的面积是最大的.输出M2的面积.   Input 第1行:2个数m,n中间用空格分隔(2 <= m,n <= 500)…
跟最大子矩阵差不多O(n3)扫一下.有更优写法?挖坑! #include<cstdio> #include<cstring> #include<cctype> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) int read(){ int x=0;ch…
爆零好爽,被中学生虐好爽,还好我毕业得早 求全1(或全0)子矩阵的个数,看了题解有好几种思路,我学了三种,但有两种不是很理解,而且也没另外那个跑得快,所以简单讲述一一下我会的那种来自Caro23333大佬的思路,传送门. 首先我们要知道,n*m矩阵的全部子矩阵的个数是C2n+1*C2m+1,因为n*m矩阵横的线就有n+1条,竖的线就有m+1条,而我们横的线任选两根,竖的线也任选两根就能组成一个矩阵了.我们求解的思路就是用总的矩阵数去减去不是全0(或者全1)的子矩阵数.那怎么去求出不是全0(或者全…
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1437 题意: 思路: 单调栈题.求出以每个数为区间最大值的区间范围即可. #include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<vector> #include<stack> #include<…
链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1102 思路: 首先介绍下单调栈的功能:利用单调栈,可以找到从左/右遍历第一个比它小/大的元素的位置.时间复杂度为O(n). 这道题要找最大的矩形的面积,我们可以假设i为矩形最低的高,那么对每一个i找到向左走第一个比他小的l[i],和向右走第一个比他小的r[i]. 我们可以知道当前矩阵最大为:a[i] * (l[i]-1-(r[i]-1)+1);对所有i的值取最大…
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1102 题意: 思路: 做法就是求出每个长方形向左向右所能延伸的最大距离. 我这里用单调栈来做,维护一个单调递增的栈(自底向上递增),如果当前值大于栈顶,那么直接进栈,如果小于的话,那就说明前面比它大的那些数最多只能延伸到它这里.自己手动模拟一下就可以了. #include<iostream> #include<algorithm> #include<…
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1215 1215 数组的宽度 题目来源: Javaman 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 收藏 关注 N个整数组成的数组,定义子数组a[i]..a[j]的宽度为:max(a[i]..a[j]) - min(a[i]..a[j]),求所有子数组的宽度和. Input 第1行:1个数N,表示数组的长度.(1 <= N <=…
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1102 1102 面积最大的矩形 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 关注 有一个正整数的数组,化为直方图,求此直方图包含的最大矩形面积.例如 2,1,5,6,2,3,对应的直方图如下:     面积最大的矩形为5,6组成的宽度为2的矩形,面积为10. Input 第1行:1个数N,表示数组的长度(0 <= N <=…
Description 我们将矩阵A中位于第i行第j列的元素记作A[i,j].一个矩阵A是酷的仅当它满足下面的条件:       A[1,1]+A[r,s]<=A[1,s]+A[r,1](r,s>1)其中r为矩阵A的行数,s为矩阵A的列数.进一步,如果一个矩阵是非常酷的仅当它的每一个至少包含两行两列子矩阵都是酷的.你的任务是,求出一个矩阵A中的一个非常酷的子矩阵B,使得B包含最多元素. Input 第一行包含两个整数R,S(2<=R,S<=1000),代表矩阵的行数与列数.接下来R…
[51nod 1288]汽油补给(ST表+单调栈) 题面 有(N+1)个城市,0是起点N是终点,开车从0 -> 1 - > 2...... -> N,车每走1个单位距离消耗1个单位的汽油,油箱的容量是T.给出每个城市到下一个城市的距离D,以及当地的油价P,求走完整个旅途最少的花费.如果无法从起点到达终点输出-1. 分析 贪心考虑,当我们到达一个城市x的时候,我们下一个到的城市应该是在x加满油的情况下,能到达的油价比x低的城市.如果每个加油城市之间的路都这样走,那么最后的价钱一定是最小的.…
题目描述: 自己的提交: class Solution: def countSquares(self, matrix: List[List[int]]) -> int: if not matrix: return 0 m,n = len(matrix),len(matrix[0]) dp = [0] + [0] * m * n for i in range(m): for j in range(n): dp[i*n+j+1] = dp[i*n+j] layer = min(i,j) for l…
在一个由 0 和 1 组成的二维矩阵内,找到只包含 1 的最大正方形,并返回其面积. 示例: 输入: 1 0 1 0 01 0 1 1 11 1 1 1 11 0 0 1 0 输出: 4 来源:力扣(LeetCode) 解题思路给定矩阵每一个1 代表边长为1的正方形,0代表不存在;dp[dp[i][$j]存储当前位置的的最大边长 这边使用循环 遍历方式存储可能存在的值 1.x 代表矩阵的列数,x代表矩阵的列数,y代表矩阵的行数2.当i==0||i==0∣∣j==0||matrix[matrix[…
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1215 题意: 思路: 计算出以第i个数为最大值的区间范围,l_max[i]为左端点,r_max[i]为右端点,计算最小值同理可得. 计算出了区间范围,就可以计算出每个数对于答案的贡献值. #include<iostream> #include<algorithm> #include<cstring> #include<cstdio>…
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1349 题意: 求区间内最大值大于等于k的区间个数. 思路: 利用求出对于以a[i]为最大值的区间范围,pre[i]表示左端范围,aft[i]表示右端范围,则区间个数为$(i-pre[i]+1)*(aft[i]-i+1)$. #include<iostream> #include<algorithm> #include<cstring> #inc…
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1279 1279 扔盘子 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 收藏 关注 有一口井,井的高度为N,每隔1个单位它的宽度有变化.现在从井口往下面扔圆盘,如果圆盘的宽度大于井在某个高度的宽度,则圆盘被卡住(恰好等于的话会下去). 盘子有几种命运:1.掉到井底.2.被卡住.3.落到别的盘子上方. 盘子…
利用单调栈,高效求出每个区间内的最大值和次大值的亦或值. 先正向扫描,利用单调递减栈,若当前栈为空栈,则直接压入栈中,若为非空栈,弹出栈顶元素,每弹出一个元素,则求一次亦或值,保留最大值 接着进行反向扫描,过程与上相似. #include<stdio.h> #include<math.h> #include<cstring> #include<stack> #include<iostream> #include<algorithm>…
利用单调栈高效的求出,一个数a[i]在哪个区间内可作为最小值存在. 正向扫描,求出a[i]可做为最小值的区间的左边界 反向扫描,求出a[i]可作为最小值的区间的右边界 r[i] - l[i] +1 就是a[i]可作为最小值的区间的 最大长度 我们知道:长度为len的区间,包含长度为len-1的区间 所以最后,需要逆向[确保无后效性]更新答案数组,保留最大值. #include<stdio.h> #include<math.h> #include<cstring> #in…
题目要求是求出两个序列中处于相同位置区间并且最大值相同的区间个数,我们最直观的感受就是求出每个区间的最大值,这个可以O(N)的求,利用单调栈求出每个数作为最大值能够覆盖的区间. 然后我们可以在进行单调栈的时候统计一下答案,怎么统计呢?就是在一个数列弹栈的时候在另一个数列的单调栈中找到这个数,然后分别算出两个数列中所对应的区间,然后统计一下左端点和右端点能够取到的所有位置利用乘法原理求一下即可.—— by VANE #include<bits/stdc++.h> using namespace…
3039: 玉蟾宫 Time Limit: 2 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地.这片土地被分成N*M个格子,每个格子里写着'R'或者'F',R代表这块土地被赐予了rainbow,F代表这块土地被赐予了freda.现在freda要在这里卖萌...它要找一块矩形土地,要求这片土地都标着'…
维护两个单调递减的栈,当i加进栈,位置x的数弹出的时候,在另一个栈中找到和这个数一样大的数,计算贡献(x-靠右左端点)*(i-x). #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<algorithm> #define ll long long using namespace std; ,inf=1e9; int n,m,x,y,z,…
对于每一个i找到最近的j满足最大值-最小值>K,对答案的贡献为j-i,用单调队列维护最值即可 #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<algorithm> #include<queue> #include<cmath> #include<map> #define ll long lon…
单调栈求每个数在哪些区间是最值的经典操作. 把数一个一个丢进单调栈,弹出的时候[st[top-1]+1,i-1]这段区间就是弹出的数为最值的区间. poj2796 弹出的时候更新答案即可 #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<algorithm> #include<queue> #include<cmath…
N个整数组成的序列a[1],a[2],a[3],…,a[n],你可以对数组中的一对元素进行交换,并且交换后求a[1]至a[n]的最大子段和,所能得到的结果是所有交换中最大的.当所给的整数均为负数时和为0. 例如:{-2,11,-4,13,-5,-2, 4}将 -4 和 4 交换,{-2,11,4,13,-5,-2, -4},最大子段和为11 + 4 + 13 = 28.   Input 第1行:整数序列的长度N(2 <= N <= 50000) 第2 - N + 1行:N个整数(-10^9 &…
题目传送门 题目大意: 一个矩阵中,求F组成的矩阵的面积,(答案乘以三). 思路:n如果是小于100的,就可以通过前缀和,然后三重循环暴力找,和poj1050很像,但由于是1000,就不可以了,时间复杂度太高. 这道题的类别是单调栈,仔细想一下,发现其实就是先统计每一行网上有多少个长方形,然后再枚举每一行,算出最大的maxx,相当于poj2559的加强版.代码有很多细节要注意,最大的坑是,输入的图,两个符号之间不一定只有一个空格,所以每一个字符都要用%s输入,对拍拍了好久都不知道错哪里,看了题解…
 区间计数   基准时间限制:1.5 秒 空间限制:262144 KB 分值: 80   两个数列 {An} , {Bn} ,请求出Ans, Ans定义如下: Ans:=Σni=1Σnj=i[max{Ai,Ai+1,...,Aj}=max{Bi,Bi+1,...,Bj}] 注:[ ]内表达式为真,则为1,否则为0.     1≤N≤3.5×1051≤Ai,Bi≤N    样例解释: 7个区间分别为:(1,4),(1,5),(2,4),(2,5),(3,3),(3,5),(4,5) Input 第…
Largest Submatrix of All 1’s Given a m-by-n (0,1)-matrix, of all its submatrices of all 1’s which is the largest? By largest we mean that the submatrix has the most elements. Input The input contains multiple test cases. Each test case begins with m …
思路: 对于这个高度往左能延伸最远x,往右能延伸最远y,(x+1+y)*w; 利用单调栈就行了: #include <cstdio> #include <stack> #include <iostream> #include <string.h> #include <algorithm> using namespace std; typedef long long LL; const int N=5e4+10; struct asd{ LL pr…