• poj 3250 bad hair day


    题目大意:

    一个数列,求对于每个ai右边有几个比它小的数,且这些比他小的数到ai之间没有比ai大的数。

    思路:

    问题可以很容易地转换为求右边第一个大于等于它的数的位置

    然后就可以想到单调栈

    有两种做法:

    一:

    从后向前走,栈内为单调递减,栈内元素需要记录一下它的值和位置,然后每个元素进来的时候弹出直到栈顶比该元素小,答案加上栈顶到现在位置的距离即可

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<queue>
     8 #include<vector>
     9 #include<set>
    10 #define inf 2147483611
    11 #define ll long long
    12 #define MAXN 80101
    13 using namespace std;
    14 inline int read()
    15 {
    16     int x=0,f=1;
    17     char ch;ch=getchar();
    18     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    19     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    20     return x*f;
    21 }
    22 struct data
    23 {
    24     int pos,val;
    25 }st[MAXN];
    26 int n,a[MAXN],top;
    27 ll ans;
    28 int main()
    29 {
    30     n=read();
    31     for(int i=1;i<=n;i++) a[i]=read();
    32     st[++top].val=inf,st[top].pos=n+1;
    33     for(int i=n;i>=1;i--)
    34     {
    35         while(st[top].val<a[i]&&top) top--;
    36         st[++top].pos=i,st[top].val=a[i];
    37         ans+=st[top-1].pos-i-1;
    38     }
    39     printf("%lld",ans);
    40 }
    View Code

    二:

    首先可以知道答案可以转化为每个点左边有几个比它大的数且之间没有更大的数则:

    从前向后走,栈内为单调递减,栈内元素只需要记录一下它的值,然后对于每个点,我们弹出同上,答案只需要加上当前站内元素数,然后再把元素加入栈。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<queue>
     8 #include<vector>
     9 #include<set>
    10 #define inf 2147483611
    11 #define ll long long
    12 #define MAXN 80101
    13 using namespace std;
    14 inline int read()
    15 {
    16     int x=0,f=1;
    17     char ch;ch=getchar();
    18     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    19     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    20     return x*f;
    21 }
    22 int n,h,st[MAXN],top;
    23 ll ans;
    24 int main()
    25 {
    26     n=read();
    27     for(int i=1;i<=n;i++)
    28     {
    29         h=read();
    30         while(top&&st[top-1]<=h) top--;
    31         ans+=top;
    32         st[top++]=h;
    33     }
    34     printf("%lld",ans);
    35 }
    View Code
  • 相关阅读:
    【9901】数塔问题
    【9704】&&【9109】麦森数
    Javascript继承机制的设计思想
    Javascript继承机制的设计思想
    儿子和女儿——解释器和编译器的区别与联系
    Firebug控制台详解
    Firebug控制台详解
    linux 下 自己写的 html文件产生中文乱码问题 解决办法
    linux 下 自己写的 html文件产生中文乱码问题 解决办法
    (译)Objective-C的动态特性
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/7617103.html
Copyright © 2020-2023  润新知