hdu~3410(单调队列)
2015-04-21 11:07
127 查看
单调队列就是队列中的元素是单调递增或递减的。比如把 5 2 3 1 4 入队:
减:、、、、、、、、、、、增:
5 、、、、、、、、、、、、5
5 2 、、、、、、、、、、、2
5 3 、、、、、、、、、、、2 3
5 3 1、、、、、、、、 、、1
5 4 、、、、、、、、、、、1 4
这个还是好理解的,但是,我们得会用单调队列这一特性去解决题目,抽象出题目中有类似的操作。
Passing the Message
题意:
给你n个数a[1~n],让你输出两行数据,每行n个数。
1.对于第一行的n个数l[1~n]:把第k个数记为x,
x就是 在a[k]左边第一个比a[k]大的数 到 a[k]之间的数中(不包括这两个),最大的那个数的下标。
比如:2 5 1 2 3 4
对于 l[6],左边比他小的是 a[3]=1 a[4]=2 a[5]=3 ,a[5] 最大,所以l[6]=5;
2.对于第二行r[1~n]就是从右边开始,其他定义和第一行一样。
测试数据 :5 2 4 3 1
a[1]=5左边比他的的是a[0],a[0]到a[1]之间没有数l[1]=0;
a[2]=2左边比他的的是a[1]=5,a[1]到a[2]之间没有数,l[2]=0;
a[3]=4左边比他大的数a[1]=5,在a[1]< <a[3]之间,有一个a[2],所以l[3]=2;
a[4]=3左边比他的的是a[3]=4,a[3]到a[4]之间没有数,l[4]=0;
a[5]=1左边比他的的是a[4]=3,a[4]到a[5]之间没有数,l[5]=0;
具体的不说了,上代码,看注释呗:
减:、、、、、、、、、、、增:
5 、、、、、、、、、、、、5
5 2 、、、、、、、、、、、2
5 3 、、、、、、、、、、、2 3
5 3 1、、、、、、、、 、、1
5 4 、、、、、、、、、、、1 4
这个还是好理解的,但是,我们得会用单调队列这一特性去解决题目,抽象出题目中有类似的操作。
Passing the Message
题意:
给你n个数a[1~n],让你输出两行数据,每行n个数。
1.对于第一行的n个数l[1~n]:把第k个数记为x,
x就是 在a[k]左边第一个比a[k]大的数 到 a[k]之间的数中(不包括这两个),最大的那个数的下标。
比如:2 5 1 2 3 4
对于 l[6],左边比他小的是 a[3]=1 a[4]=2 a[5]=3 ,a[5] 最大,所以l[6]=5;
2.对于第二行r[1~n]就是从右边开始,其他定义和第一行一样。
测试数据 :5 2 4 3 1
a[1]=5左边比他的的是a[0],a[0]到a[1]之间没有数l[1]=0;
a[2]=2左边比他的的是a[1]=5,a[1]到a[2]之间没有数,l[2]=0;
a[3]=4左边比他大的数a[1]=5,在a[1]< <a[3]之间,有一个a[2],所以l[3]=2;
a[4]=3左边比他的的是a[3]=4,a[3]到a[4]之间没有数,l[4]=0;
a[5]=1左边比他的的是a[4]=3,a[4]到a[5]之间没有数,l[5]=0;
具体的不说了,上代码,看注释呗:
#include <stdio.h> #include <deque> #define INF 0xfffffff using namespace std; int main() { int t,ti; int l[50005],r[50005],a[50005]; scanf("%d",&t); for(int ti=1;ti<=t;ti++){ int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); deque <int >q; for(int i=1;i<=n;i++) //左边开始 { int sign=1,last=0; while(!q.empty() && a[q.back()]<a[i]) { //维护单调队列,对头的元素最大 sign=0; last=q.back(); q.pop_back(); } if(sign) l[i]=0; //若未弹出一个元素,则a[i-1] > a[i] else l[i]=last; //否则,最后弹出的一个元素 必是 在比a[i]小的元素中,最大的那个 q.push_back(i); } for(int i=n;i>=1;i--) //右边开始,同上 { int sign=1,last=0; while(!q.empty() && a[q.back()]<a[i]) { sign=0; last=q.back(); q.pop_back(); } if(sign) r[i]=0; else r[i]=last; q.push_back(i); } printf("Case %d:\n",ti); for(int i=1;i<=n;i++) printf("%d %d\n",l[i],r[i]); } return 0; }
相关文章推荐
- hdu 3410 Passing the Message(单调队列)
- hdu-3410 Passing the Message[单调队列]
- hdu 3410(单调队列)
- Hdu 3410 【单调队列】.cpp
- HDU 3410 && POJ 3776 Passing the Message 单调队列
- HDU 3410 && POJ 3776 Passing the Message 单调队列
- hdu 3410(单调队列)
- HDU 4122 POJ 4002 Alice's mooncake shop(单调队列)
- hdu 5261 蜀道难 (单调队列)@
- HDU 3530 Subsequence(单调队列)
- 股票交易 【SCOI 2010】HDU 3401 (单调队列优化DP入门)
- HDU 3401 Trade(用单调队列优化DP)
- hdu~3530(单调队列)
- [DP] hdu 4374 One hundred layer #单调队列优化
- HDU 4193 Non-negative Partial Sums(单调队列)
- HDU 1003 Max Sum + 单调队列优化dp解法
- 【HDU 5945】 Fxx and game 【单调队列优化dp】
- hdu 5945 (dp+单调队列,BestCoder Round #89)
- hdu 4193 单调队列
- HDU 5033 Building 单调队列