• 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
  • 相关阅读:
    [Machine Learning]Numpy
    [LeetCode]Valid Palindrome
    [LeetCode]Remove Linked List Elements
    [LeetCode]Reverse Linked List
    [LeetCode]Palindrome Number
    Spring绑定请求参数过程以及使用@InitBinder来注册自己的属性处理器
    servlet温故知新
    线程池简单实现
    JAVA NIO学习笔记
    XSS攻击简单介绍
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/7617103.html
Copyright © 2020-2023  润新知