POJ 2823 单调队列

KD的单调队列啊!! 十分坑啊~~ 整个下午都浪费在这个上面了~虽然优化到了5400ms+了,但是离那些500ms+的神犇们差距太远了... 应该是有很好的算法吧,只能一个人想了。

使用单调队列... 无限TLE啊... 没看代码只是自己YY了一遍大概怎么弄。我理解的的单调队列大概是这个样子。

拿样例来说事吧。觉得类似于网络协议中的窗口协议。

8 3
1 3 -1 -3 5 3 6 7
窗口大小为3

每次更新单调队列

1.{ 1 };

2.{ 1,3 };

3.{ -1 };  输出-1

4.{ -3 };输出-3

5.{ -3,5 };输出-3

6.{ -3,3 };输出-3

7.{ 3 }->{ 3,6 };输出3

8.{ 3,6,7 };输出3

同样地对于max序列。

可见规律为:每次输出队头元素,当前元素从队尾走向队头,插入第一个符合条件的地方。保证队列单调,而且相同的元素尽可能的大,这样每次维持一个队列。输出最前段的元素。但是判断插入的时候不能从前面向后扫描,这样时间开销太大了我就果断的TLE了一下午,查不出错误,后来就队尾向前扫一遍,找到节点插入就行了。

KD的单调队列啊~~


#include<iostream>
#define MAXN 1000005
using namespace std;

int date[MAXN];
int temp[MAXN];

int main()
{
    int n,c;
    int foot=1;
    int index=1;
    int i,pre;
           
    while( scanf( "%d %d",&n,&c )!=EOF )
    {
           memset( date,0,sizeof(date) );
           memset( temp,0,sizeof(temp) );
           for( i=1;i<=n;i++ )
                scanf( "%d",&date[i] );
           //memset( temp,0,sizeof(temp) );
           temp[1]=1;
           foot=2;index=1;
           for( i=1;i<=n;i++ )
           {
                if( i-temp[index]+1>c )
                    index++;
                pre=foot;
                while(1)
                {
                        if( date[i]<=date[temp[pre-1]]&& pre-1>=index )
                            pre--;
                        else
                            break;
                }
                foot=pre+1;
                temp[pre]=i;
                if( i==c )
                    printf( "%d",date[temp[index]] );
                if( i>c )
                    printf( " %d",date[temp[index]] );
           }
           printf( "\n" );
           foot=2;index=1;
           temp[1]=1;
           for( i=1;i<=n;i++ )
           {
                if( i-temp[index]+1>c )
                    index++;
                pre=foot;
                while(1)
                {
                        if( date[i]>=date[temp[pre-1]]&&pre-1>=index )
                            pre--;
                        else
                            break;
                }
                foot=pre+1;
                temp[pre]=i;
                if( i==c )
                    printf( "%d",date[temp[index]] );  
                if( i>c )
                    printf( " %d",date[temp[index]] );
           }
           printf( "\n" );
    }
    return 0;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值