【算法学习笔记】53.单调队列的简单应用 SJTU OJ 1034 二哥的金链
2015-05-27 23:33
477 查看
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)
注意此处把环形过程简化成了数组,用空间换了代码简洁性[/code]
#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; }
相关文章推荐
- 【算法学习笔记】91.简单森林计数 SJTU OJ 1045 二哥的家族
- 【算法学习笔记】24.记忆化搜索 解题报告 SJTU OJ 1002 二哥种花生
- 【算法学习笔记】45. 二分答案 BFS路径 SJTU OJ 1031 二哥在黄山
- 【算法学习笔记】46.拓扑排序 优先队列 SJTU OJ 3010 Complicated Buttons
- 【算法学习笔记】54.约瑟夫问题 模拟、逆推动规 SJTU OJ 1038 二哥的约瑟夫
- 【算法学习笔记】78. STL二分的练习 下标映射的处理技巧 SJTU OJ 1053 二哥的内存
- 【算法学习笔记】79.STL 优先队列 模拟法 SJTU OJ 4012 合并果子
- 【算法学习笔记】80.二维动态规划 SJTU OJ 3022 二哥要翘课
- 【算法学习笔记】87. 枚举路径 SJTU OJ 1999 二哥找宝藏
- 【算法学习笔记】23.动态规划 解题报告 SJTU OJ 1280 整装待发
- 【算法学习笔记】23.动态规划 解题报告 SJTU_OJ 1280 整装待发
- 【算法学习笔记】26.扫描维护法 解题报告 SJTU OJ 1133 数星星
- 【算法学习笔记】27.动态规划 解题报告 SJTU OJ 1254 传手绢
- 【算法学习笔记】28.枚举法 解题报告 SJTU OJ 1255 1256 魔戒
- 【算法学习笔记】29.规律题 解题报告 SJTU OJ 1101 SuperXOR
- 【算法学习笔记】31.动态规划 SJTU OJ 1320 numtri
- 【算法学习笔记】32.计算几何 求含最多给定点的直线 SJTU OJ 1350 穿越沙漠
- 【算法学习笔记】33.在线算法 SJTU OJ 1006 求和游戏
- 【算法学习笔记】34.高精度除法 SJTU OJ 1026/1016
- 【算法学习笔记】35.高精度 竖式乘法 SJTU OJ 1274