【问题描述】

现在有n个宽度为1的矩形按如下图(左边的)所示的方式排在了一起:

用肉眼容易看出,在左图内部面积最大的矩形如右图绿色部分所标注。

现在我们考虑将其中一些宽度为1的矩形取出,按照原顺序再次紧密地靠在一起,比如在原图中,如果我们取出从左往右数的第2、4、5、6个矩形,那么我们得到下面的左图,而该图形内部的最大矩形则如右图黄色部分所示。

现在,你的任务就是从原图中取出若干个宽度为1的矩形并使用上面的方式组成新的图形,使得新的图形中,内部的最大矩形面积最大。

【输入格式】

第一行为一个正整数T,表示数据组数。 接下来T组数据,每组数据第一行为一个正整数n,表示矩形个数,接下来一行n个正整数,第i个数hi表示图形中从左到右第i个矩形的高度。

【输出格式】

对每组数据输出一行一个正整数,表示最大的“最大矩形”面积。

【输入样例】
3
4
1 2 3 4
3
8 1 9
3
8 6 9
【输出样例】
6
16
18
【数据规模与约定】

对于30%的数据,有1<=n<=15,

对于60%的数据,有1<=n<=1000,

对于100%的数据,有1<=T<=10, 1<=n,hi<=100000,每个测试点n的和不超过200000。

题目分析

这是一个裸的单调栈,我转载了别人的代码如下。设第一个比当前数(序号为i)小的左侧数为left[i]。算法的流程是这样的:设现在程序循环到第i个数,如果当前,栈顶的数大于等于第i个数,说明什么?说明序号i以后的数j,它们的left[j]一定不会是栈顶那个数,因为选了j一定能选i。既然这样,直接把j从栈中弹出,然后继续判断……直至第i个数遇到比它小的栈顶的数。这个数就是left[i],因为比i小的数只会被更小更优的数替换。然后,将i入栈。这样就把那些无用的,值大于第i个数,却在第i个数左边的数统统用第i个数替换了。这就去除了冗余状态。

代码实现

#include<bits/stdc++.h>
using namespace std;
#define N 100001
#define int long long
int s[N],a[N],w[N],T,n,top,ans;
signed main(){
freopen("rectangle.in","r",stdin),freopen("rectangle.out","w",stdout);
cin>>T;
while (T--){
cin>>n;
for (register int i=;i<=n;++i) cin>>a[i];
sort(a+,a+n+);
a[n+]=top=ans=;
for (register int i=;i<=n+;++i)
if (s[top]<a[i]&&top)
s[++top]=a[i],w[top]=;
else{int wide=;
while(s[top]>=a[i]&&top){
wide+=w[top];
ans=max(ans,wide*s[top--]);
}s[++top]=a[i],w[top]=wide+;
}cout<<ans<<"\n";
}
return ;
}

代码分析

原来的HDU1506也是很水,这一题也是,唯一的区别在于排序了。我将会认真的讲解一下单调栈问题。

我们要维护的栈是一个单调递增的数列,为什么呢?我们的答案最好是用较高的答案加上去的,所以用递增数列。我们的答案矩阵是长乘宽,我们维护一个队列,当前的数字比栈顶还大,自然是递增的,入栈即可。如果小于等于,我们保存的是栈中比这个数字小(等于)的数字,当然这时候我们把宽度加一下啊。。。因为这时候我们维护的矩形可能是最大的,自然要记录了。我们一边出栈一边更新答案,虽然有可能不会更新掉答案。这里贼骚:原来的宽度是不是被pop掉了?我们再把宽度加回去哈。居然有这种操作,原因是原来的部分被算过一遍了,我们如果有更新ans就更新过了,我们可以把这个部分当做一个小矩形加入栈里面。如果最后还有答案怎么办啊?我们用一个高度为0的矩形入栈,然后你懂得。

当然如果你要压行,我不介意。本来要讲一讲我和小姐姐的故事,下次再说。

【FZSZ2017暑假提高组Day1】最大矩形的更多相关文章

  1. 【FZSZ2017暑假提高组Day1】华容道游戏

    [问题描述] 华容道是一种有趣的滑块游戏,大概是下面这个样子的. 游戏局面由一个2*2的曹操滑块,五个2*1的蜀将滑块(横竖是不定的).四个1*1的小兵滑块以及两个空的位置构成,玩家需要利用空的位子移 ...

  2. 【FZSZ2017暑假提高组Day1】确定小组

    [问题描述] 有n个人坐成一排,这n个人都在某一个小组中,同一个小组的所有人所坐的位置一定是连续的. 有一个记者在现场进行采访,他每次采访都会询问一个人其所在的小组有多少人,被询问的每个人都给出了正确 ...

  3. 【FZSZ2017暑假提高组Day2】圆盘时钟

    [问题描述] 作为出题人的小Z相信大家对上图这样的圆盘时钟都不会陌生——在理想圆盘时钟上,秒针每一分钟转一圈,分针每一小时转一圈,时针每12小时转一圈,它们均是匀速转动的,在0点时三条针均指向表盘上的 ...

  4. luogu1003铺地毯[noip2011 提高组 Day1 T1]

    题目描述 为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯.一共有 n 张地毯,编号从 1 到n .现在将这些地毯按照编号从小到大的顺序平行于 ...

  5. Noip2011 提高组 Day1 T1 铺地毯 + Day2 T1 计算系数

    Day1 T1 题目描述 为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯.一共有 n 张地毯,编号从 1 到n .现在将这些地毯按照编号从小 ...

  6. 18/9/9牛客网提高组Day1

    牛客网提高组Day1 T1 中位数 这好像是主席树??听说过,不会啊... 最后只打了个暴力,可能是n2logn? 只过了前30%  qwq #include<algorithm> #in ...

  7. Noip2011 提高组 Day1 T3 Mayan游戏

    题目描述 Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个 7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游戏通关是指在规定 ...

  8. GZOJ 1361. 国王游戏【NOIP2012提高组DAY1】

    国王游戏[NOIP2012提高组DAY1] Time Limit:1000MS Memory Limit:128000K Description 国王游戏(game.cpp/c/pas) [问题描述] ...

  9. 暑假提高组集训Day1 T1

    说实话,今天的题真的有点难! ~备受打击~ 我们先来看一看第一题吧 看起来好像不太简单,其实并不难 下面来提供两种方法吧 1.做法一 //签到题 /* 那么这一题就是告诉你n个点的坐标,把它们分别放到 ...

随机推荐

  1. ceph存储集群性能测试工具步骤(初稿)

    一.源码安装fio工具: #yum install libaio-devel make #wget http://brick.kernel.dk/snaps/fio-2.2.10.tar.gz #ta ...

  2. BOM浏览器

    1.window.open(url,ways) url是打开的网页地址 ways 是打开的方式 2.window.close() 3.window.navigator  浏览器用户信息 4.windo ...

  3. 剑指Offer 14. 链表中倒数第k个结点 (链表)

    题目描述 输入一个链表,输出该链表中倒数第k个结点. 题目地址 https://www.nowcoder.com/practice/529d3ae5a407492994ad2a246518148a?t ...

  4. 《CSS揭秘》之毛玻璃效果知识点

    实现代码: CodePen:毛玻璃效果 Dabblet:毛玻璃效果 HTML: <main> <blockquote> <em>"The only way ...

  5. leetcode 3.Longest Substring Without Repeating Charcters

    在一个字符串中寻找出最长的无重复字符的子串的,在不断的后续检索中需要去掉前面一个重复的字符,那么就是需要记录之前所出现过的字符的,在这里需要利用hashmap来记录字符和其出现的位置之间的映射关系的, ...

  6. 20155208 徐子涵 Exp3 免杀原理与实践

    20155208 徐子涵 Exp3 免杀原理与实践 基础问题回答 (1)杀软是如何检测出恶意代码的? 一种是基于特征码的检测,另一种是基于恶意行为的检测. (2)免杀是做什么? 在我看来,免杀就是要达 ...

  7. _proto_ && prototype (原型 && 原型链)

    原型一直都是JavaScript基础里面的痛点,因为在JavaScript里面没有类的概念,都是通过原型对象来实现继承,下面的这个图很好的说明几者之间的关系! a.__proto__ = A.prot ...

  8. html(二)常见符号

    HTML当中的常见实体内容:

  9. python:基本统计值计算(平均数,方差,中位数)

    #CalStatisticsV1.py def getNum(): #获取用户不定长度的输入 nums=[] test=input("请输入要存储的数据(回车退出):") whil ...

  10. Nmap使用指南

    一.目标指定 1.CIDR标志位 192.168.1.0/24 2.指定范围 192.168.1.1-255 192.168.1-255.1(任意位置) 3.IPv6地址只能用规范的IPv6地址或主机 ...