POJ3250-Bad Hair Day(单调栈,与下一个最大/小元素之间的个数)

POJ3250 Bad Hair Day

题干:

n n n头牛从左到右排成一排,每头牛有一个高度 h i h_i hi,设左数第 i i i头牛与「它右边第一头高度 ≥ h i \ge h_i hi」的牛之间有 c i c_i ci头牛,试求 ∑ i = 1 n c i \sum_{i=1}^nc_i i=1nci

Input: 
6
10 3 7 4 12 2
Output: 5

解:

维护一个单调递不递增栈,逆序遍历数组 h h h,若栈顶元素对应的高度 < h [ i ] <h[i] <h[i]则弹出,直到不满足这个条件; h [ i ] h[i] h[i]与其之后第一个 ≥ h [ i ] \ge h[i] h[i]的元素(下标为 t t t)之间的元素个数就是 t − i − 1 t-i-1 ti1(若栈为空说明这样的元素不存在, h [ i ] h[i] h[i]能一直看到末尾,个数为 n − i − 1 n-i-1 ni1),求和即可。

ll sum = 0ll;
    for(int i = n-1; i >= 0; i--){
        while(!st.empty() && h[st.top()] < h[i]){
            st.pop();
        }
        sum += st.empty()? (n - i- 1ll): (st.top()-i-1ll);
        if(!st.empty()&&h[st.top()]==h[i]) st.pop(); //不加这句,维护的是一个单调不递增栈,都可以
        st.push(i);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值