贪心

简介: AcWing 134. 双端队列

贪心

问题一:怎么使用双端队列排序?

我们需要把一段没有排序的数字输入到双端队列中并且排好序了,怎么操作呢

  1. 首先插入第一个数字
  2. 后续数字如果比队尾数字大,就从后边插入
  3. 如果比队头元素小,就从前面插入
  4. 除此之外,如果它即比队头大,又比队尾小,那么这个队列不能将他排序,需要在开一个队列

后面插入的下标都会更大,第一个数的下标为1

结论:用双端队列排好序后,里面数的下标呈现 单谷性质(先单调递减,后单调递增)


所以说:

第一:我们先将序列排好序,观察他们的坐标,他们的坐标呈现几个单谷,就需要几个双端队列

第二:排好序后, 值一样的数可以相互交换下标,这样并不影响这个有序的序列

问题转化为:我们如何操作,使谷峰最少?

先找到值一样的数里面,下标的最大最小值maxv,minv;

Whiteboard.png

基于以上贪心思路,可以使波谷出现次数最少。

if(st == -1)                                    //初始为下降状态
        {
            if(maxv < last) last = minv;        //第一种
            else 
            {
                st = 1;
                last = maxv;                    //第二种
            }
        }
        else
        {
            if(last < minv) last = maxv;        //第三种
            else
            {
                res ++ ;
                last = minv;                    //第四种
                st = -1;
            }
        }

AC

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
typedef pair<int, int> PII;
const int N = 2e5 + 10;

int n;
PII a[N];

int main()
{
    cin >> n;
    for(int i = 0; i < n; i ++ )
    {
        cin >> a[i].first;
        a[i].second = i;
    }
    sort(a, a + n);
    
    int res = 1;
    int last = n + 1;
    int st = -1;
    int i = 0;
    while(i < n)
    {
        int j = i;
        while(j < n && a[j].first == a[i].first) j ++ ;
        
        int minv = a[i].second;
        int maxv = a[j - 1].second;
        if(st == -1)
        {
            if(maxv < last) last = minv;
            else 
            {
                st = 1;
                last = maxv;
            }
        }
        else
        {
            if(last < minv) last = maxv;
            else
            {
                res ++ ;
                last = minv;
                st = -1;
            }
        }
        i = j;
    }
    cout << res << endl;
    return 0;
}
目录
相关文章
|
C++
NYOJ 448(贪心)
寻找最大数时间限制:1000 ms | 内存限制:65535 KB 难度:2描述 请在整数 n 中删除m个数字, 使得余下的数字按原次序组成的新数最大, 比如当n=92081346718538,m=10时,则新的最大数是9888   输入 第一行输入一个正整数T,表示有T组测试数据每组测试数据...
783 0
|
算法 C++
Huffman树(贪心)
复习acwing算法基础课的内容,本篇为讲解基础算法:贪心——Huffman树,关于时间复杂度:目前博主不太会计算,先鸽了,日后一定补上。
103 0
Huffman树(贪心)
|
算法
推公式(贪心)
复习acwing算法基础课的内容,本篇为讲解基础算法:贪心——推公式,关于时间复杂度:目前博主不太会计算,先鸽了,日后一定补上。
109 0
推公式(贪心)
贪心初步-A - Doing Homework again
Doing Homework again Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7494    Accepted S...
1002 0
|
人工智能
NYOJ 106(贪心)
  背包问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 现在有很多物品(它们是可以分割的),我们知道它们每个物品的单位重量的价值v和重量w(1
685 0
|
人工智能 BI
【第六讲】 贪心
【第六讲】 贪心
|
机器学习/深度学习 算法 C++
简单的贪心
简单的贪心
71 0
|
算法
贪心题:股票买卖 II
贪心题:股票买卖 II
71 0
|
9月前
|
存储 算法 Java
贪心算法和动态规划
贪心算法和动态规划
111 0

热门文章

最新文章