zoukankan      html  css  js  c++  java
  • 51Nod-1102 面积最大的矩形 (DP或单调栈)

    基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题
     收藏
     关注
    有一个正整数的数组,化为直方图,求此直方图包含的最大矩形面积。例如 2,1,5,6,2,3,对应的直方图如下:
     
     
    面积最大的矩形为5,6组成的宽度为2的矩形,面积为10。
     
    Input
    第1行:1个数N,表示数组的长度(0 <= N <= 50000)
    第2 - N + 1行:数组元素A[i]。(1 <= A[i] <= 10^9)
    Output
    输出最大的矩形面积
    Input示例
    6
    2
    1
    5
    6
    2
    3
    Output示例
    10
    参考博客链接:https://blog.csdn.net/queuelovestack/article/details/52326276

    1:DP
    关键是:预处理 每个高度 对应的能“扩张”最左边left的位置,和能“扩张”最右边right的位置
     1 #include<stdio.h>
     2 #include<algorithm>
     3 #include<string.h>
     4 using namespace std;
     5 int l[50005];
     6 int r[50005];
     7 long long n[50005];//这个要放main外面,放main里面会超时
     8 int main()
     9 {
    10     int N;
    11     long long sum=0;
    12     scanf("%d",&N);
    13     for(int i=1;i<=N;i++)
    14     scanf("%d",&n[i]);
    15     n[0]=0;//确保left[1]的值为1
    16     n[N+1]=0;//确保right[N]的值为N
    17     int k;
    18     for(int i=1;i<=N;i++)
    19     {
    20         k=i-1;
    21         while(n[i]<=n[k])
    22         {
    23             k=l[k]-1;
    24         }
    25         l[i]=k+1;
    26     }
    27     for(int i=N;i>=1;i--)
    28     {
    29         k=i+1;
    30         while(n[i]<=n[k])
    31         {
    32             k=r[k]+1;
    33         }
    34         r[i]=k-1;
    35     }
    36     for(int i=1;i<=N;i++)
    37     {
    38         sum=max(sum,(r[i]-l[i]+1)*n[i]);
    39     }
    40     printf("%lld
    ",sum);
    41     return 0;
    42 }
    
    

    2:单调栈

    弄一个单调栈存储,形成一个单调递增栈。

    假设这些数为2,5,8,4,1(对应下标为0-4)

    Tip:这里入栈入的并不是number的值....

    如果新进入的值比已经入栈对应的值大(或者栈空了),则入栈。(例如这里一开始栈空,所以入栈2,5,8)

    当遇到新进入的值小于当前栈顶对应的值时,表明此时该“高度”不可能再往右边扩张,所以已经达到该高度扩张的最大范围。则可以进行计算算出该高度的最大值,并更新。

    例如当到4时,则达到该高度扩张最大范围,高度8对应的最大值是8("(i-s.top())*number[top]"),高度8最大值的最大值计算完毕8对应位置即可出栈

    (因为8对应位置出栈所以,此时5为栈定)所以高度为5对应的最大值是10("(i-s.top())*number[top]"),计算完后5对应位置出栈

    但是4>2所以2还没扩张到最大范围,所以不计算2对应的的最大值

    这是更新完后的栈。

    同理:现在遇到1,1<number[s.top()]即(1<4),表明栈中对应的达到最大范围,所以高度4对应的最大值为(i-s.top())*number[s.top],即(4-1)*4=12,计算完出栈

    然后,2对应位置为栈定,又因为1<2所以表明高度2也达到最大值,高度2对应的最大值为(i-s.top())*number[s.top],即(4-0)*2=8,计算完对应位置出栈。

    1入栈。

    Tip:    number[N]=-1;是为了让最后一个元素也能计算出最大值

     1 #include<stdio.h>
     2 #include<stack>
     3 using namespace std;
     4 long long number[50005];
     5 int main()
     6 {
     7     stack<int>s;
     8     int N;
     9     long long sum=0;
    10     int ans;
    11     scanf("%d",&N);
    12     for(int i=0;i<N;i++)
    13     scanf("%lld",&number[i]);
    14     number[N]=-1;//确保栈中元素最大值都计算完 
    15     for(int i=0;i<=N;i++)
    16     {
    17         if(s.empty()||number[i]>=number[s.top()])
    18         {
    19             s.push(i);
    20         }
    21         else if(number[i]<number[s.top()])
    22         {
    23             while(!s.empty()&&number[i]<number[s.top()])//确保栈不为空 
    24             {
    25                 long long num=(i-s.top())*number[s.top()];//计算 number[s.top()]该高度对应的最大值 
    26                 if(num>sum) sum=num;//更新最大值 
    27                 ans=s.top();//保存循环到最后"栈顶"位置 
    28                 s.pop();//出栈 
    29             }
    30             s.push(ans);// 入栈 
    31             number[ans]=number[i];//更新这个位置的number值 
    32         }
    33     }
    34     printf("%lld
    ",sum);
    35     return 0;
    36 }
  • 相关阅读:
    SQL 中单引号 和一些特殊字符的处理
    jquery 删除table行,该如何解决
    jQuery获取Select选中的Text和Value,根据Value值动态添加属性等
    C#中DataTable
    jquery操作select(取值,设置选中)
    JS刷新页面总和!多种JS刷新页面代码!
    VS中代码对齐等快捷键
    SQL递归查询(with cte as)
    SQL Server 公用表表达式(CTE)实现递归的方法
    linux ls和 ll 命令
  • 原文地址:https://www.cnblogs.com/bendandedaima/p/9441304.html
Copyright © 2011-2022 走看看