【算法学习笔记】53.单调队列的简单应用 SJTU OJ 1034 二哥的金链

1034. 二哥的金链

Description

一个阳光明媚的周末,二哥出去游山玩水,然而粗心的二哥在路上把钱包弄丢了。傍晚时分二哥来到了一家小旅店,他翻便全身的口袋也没翻着多少钱,而他身上唯一值钱的就是一条漂亮的金链。这条金链散发着奇异的光泽,据说戴上它能保佑考试门门不挂,RP++。好心的老板很同情二哥的遭遇,同意二哥用这条金链来结帐。虽然二哥很舍不得这条金链,但是他必须用它来付一晚上的房钱了。

金链是环状的,一共有 N 节,老板的要价是 K 节。随便取下其中 K 节自然没问题,然而金链上每一节的 RP 值其实并不一样,有高有低,二哥自己非常清楚。另外二哥并不希望把整个金链都拆散了,他只愿意在这条环形的金链上切两刀,从而切下一段恰好为 K 节的金链给老板。因为 RP 值越高的节越稀有,因此他希望给老板的金链上最高的 RP 值最小。

Input Format

第一行两个整数 N 和 K,表示金项链有 N 节,老板要价 K 节。

第二行用空格隔开的N个正整数 a1...aN ,表示每一节金链的价值为多少。

Output Format

输出一个整数,表示二哥给老板的金链上最高的 RP 值最小多少。

Sample Input

5 2
1 2 3 4 5

Sample Output

2

Sample Input

6 3
1 4 7 2 8 3

Sample Output

4

最简单就是O(N*K)算法有大量重复的比较过程想消除重复比较大小的问题要考虑如何利用单调性来完成这件事情,所以就想到了单调队列。

这里维护一个单调严格递减序列就可以了,记得在考虑出队时,要根据入队的那个元素向前-K个 找到该出队的元素,与队首比较,如果是恰好是,那就出队,否则不用动,因为之前已经维护过了单调性,所以不会有比刚入队小的元素在队首位置。因为每一个元素都要经过出队入队的动作 所以是O(N+K-1)注意此处把环形过程简化成了数组,用空间换了代码简洁性
#include <iostream>
#include <cstdio>
using namespace std;

int RP[200000+1000];//存储RP
int front = 0;
int rear = 0;

bool empty(){
    return front==rear;
}

void q_out(int x){
    //因为此时x曾经肯定在队列或者已经出队了 如果队首正好是x 那就出队 否则不动
    if(que[front]==x)
        front++;
}

void q_in(int x){
    //入队时删除所有比它小的元素
    while(!empty()){
        if(que[rear-1]<x)
            rear--;
        else
            break;
    }
    que[rear++] = x;
}

void print(){
    for (int i = front; i < rear; ++i)
    {
        cout<<que[i]<<" ";
    }
    cout<<endl;
}

int main(int argc, char const *argv[])
{

    int N,K; //添加环形变化后 长度为N+K-1
    int ans = 0;
    scanf("%d%d",&N,&K);
    for (int i = 1; i <= N; ++i){
        scanf("%d",&RP[i]);
        if(i<=K-1){
            RP[N+i] = RP[i];
        }
    }
    //初始化ans
    for (int i = 1; i <= K; ++i)
    {
        if(ans < RP[i])
            ans = RP[i];
        q_in(RP[i]);
    }
    for (int i = K+1; i <= N+K-1; ++i)
    {
        q_out(RP[i-K]);
        q_in(RP[i]);
        //print();
        if(que[front] < ans)
            ans = que[front];
    }

    cout<<ans<<endl;
    return 0;
}
时间: 2024-12-20 01:12:08

【算法学习笔记】53.单调队列的简单应用 SJTU OJ 1034 二哥的金链的相关文章

【算法学习笔记】40.树状数组 动态规划 SJTU OJ 1289 扑克牌分组

Description cxt的扑克牌越来越先进了,这回牌面的点数还可以是负数, 这回cxt准备给扑克牌分组,他打算将所有的牌分成若干个堆,每堆的牌面总和和都要大于零.由于扑克牌是按顺序排列的,所以一堆牌在原牌堆里面必须是连续的.请帮助cxt计算一下,存在多少种不同的分牌的方案.由于答案可能很大,只要输出答案除以1,000,000,009的余数即可. Input Format 第一行:单个整数:N,1 ≤ N ≤ 10^6 第二行到N + 1行:在第i + 1行有一个整数:Ai, 表示第i张牌牌

【算法学习笔记】39.字符串处理 单词分割 SJTU OJ 1302 缩进格式

1302. 缩进格式 Description 小z想和小y愉快的玩耍,但是小y在写程序.程序写好了,但是小y怎么调试也过不了.小z帮小y看了一下就不想看了,因为小y虽然是萌妹子,但是她的程序缩进实在是不忍直视.于是小z决定帮她纠正. 程序里的每一行语句分为单词和空格,ASCII码从33到126的一段连续字符串是单词,而单词之间由ASCII码为32的空格分开.小z的缩进方法具体来说是这样:对于每一行的第 i 个单词,它的第一个字符的位置不能小于其它每一行的第 1 至第 i−1 个单词,且每个单词的

【算法学习笔记】35.高精度 竖式乘法 SJTU OJ 1274

Description 输入a,b 输出a*b的竖式乘法,格式见样例. Sample Input1 11 9 Sample Output1 11 9 -- 99 Sample Input2 10 10 Sample Output2 10 10 --- 100 Sample Input3 101 101 Sample Output3 101 101 ----- 101 101 ----- 10201 Sample Input4 10086 2 Sample Output4 2 10086 ----

【算法学习笔记】55.DFS 记忆化搜索 SJTU OJ 1063 小M爱滑雪

Description 小M超级喜欢滑雪~~ 滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当小M滑到坡底,便不得不再次走上坡或者等待升降机来载你.小M想知道滑雪场中最长底的滑坡.滑雪场由一个二维数组给出.数组的每个数字代表点距离水平面的相对距离.下面是一个例子 1 2 3 4 5 16 17 18 19 6 15 24 25 20 7 14 23 22 21 8 13 12 11 10 9 小M可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小.在上面的例子中,一条可滑行的

【算法学习笔记】42.正反DP 填充连续 SJTU OJ 1285 时晴时雨

1285. 时晴时雨 Description Taring 喜欢晴天,也喜欢雨天. Taring说:我想体验连续的K天的晴朗,去远足,去放歌:我还想再这K个晴天之后,再去体验连续的K天的云雨,去感受落雨时的轻语.这是令Taring最开心的事情了.其它的时间,Taring会在机房默默的编写着代码. 当然,Taring不想在这连续的K个晴天和连续的K个雨天里被机房的事务打扰或者被自然天气的变化中断.也就是说,这K个晴天和K个雨天必须是连续的,但是他们之间并不需要时间连续.显然的,Taring如果在感

【算法学习笔记】69. 枚举法 字典序处理 SJTU OJ 1047 The Clocks

我们发现这个题里每一种“移动套餐”用的次数只有0,1,2,3 是有效的,4和0是一样的. 所以我们开一个数组rot[10]来记录这9个套餐分别用了多少次. 字典序的处理和我们的枚举顺序息息相关. 我们从 000000000 到 333333333 来枚举的话,第一个符合条件的结果当然就是所有答案中字典序最小的一个了. 枚举这个排列我们需要用9个for,当然也可以用递归来实现,不过我还是喜欢视觉感比较强烈的9个for.... 在每一种排列下,我们需要通过这些套餐的方案来计算临时结果path. 然后

【算法学习笔记】44. 并查集补充 SJTU OJ 3015 露子的星空

[题目描述] 已经深夜了,露子仍然在公园里仰望星空.你走近后,她对你说:“呜—,你看夜空中的星星.它们本来都是孤独地毫无联系,但人们赋予了它们各种地联想,在它们之间连上了线,便形成了夜空中无数的星座.”你回答:“是啊.为什么我们不自己创造一个美丽的星空呢?” 假设夜空中一共有n颗星星,它们初始时都没有连线.接下来,露子会给你m条指令.一共有以下三种指令: 1.在某两颗星星间连线.(可能会重复连接两颗星星) 2.询问你当前夜空中一共有多少个星座. 3.某两颗星星当前是否属于同一个星座. 其中星座是

学习笔记:单调队列

转自:http://apps.hi.baidu.com/share/detail/34010558 [单调队列]在解一个序列某个区间段的最值问题,我们可以用到单调队列来解决.  比如poj2823 Sliding Window 就是一个很好的例子:给定一个序列,要求序列中固定长度为k 的区间中的最大值和最小值.  [原理]单调队列维护的是区间最值:  1.最大值的维护:          比如我们要维护一个区间为k的最大值的单调队列,由于新插入 的节点他的“生命力”肯定比原先已经在队列中的元素“

【算法学习笔记】24.记忆化搜索 解题报告 SJTU_OJ 1002 二哥种花生

在吴学长的代码上做了一点简化修改,本质一样.在外面铺了一圈0,让代码更简单一点,不用考虑边界情况了. 题目: http://acm.sjtu.edu.cn/OnlineJudge/problem/1002 #include <iostream> #include <string> using namespace std; int main(int argc, char const *argv[]) { int L,W; cin>>L>>W; int** su