码迷,mamicode.com
首页 > 其他好文 > 详细

【单调队列】【cogs825】【RQNOJ 167】免费午餐

时间:2015-05-27 22:59:21      阅读:141      评论:0      收藏:0      [点我收藏+]

标签:

825. [RQNOJ 167] 免费午餐

★☆   输入文件:lunch.in   输出文件:lunch.out   简单对比
时间限制:1 s   内存限制:128 MB

【问题描述】

为了增加顾客,Sally的店铺决定提供免费午餐,顿时门庭若市,但是不久Sally的原材料不足了….因此Sally决定公布一项决定:凡是来本店吃免费午餐的,一天吃能吃一次,吃的数量必须比上一次吃的少,且免费午餐将只有N个种类任君选择,为了能吃到最多的免费午餐,你将如何安排每日吃的数量呢?

【输入文件】

第一行一个数N,表示免费午餐的种类(0<=N<=100000)
第二行N个数,表示每种免费午餐的数量(0<=数量<=100000)

【输出文件】

一个数,表示最多能吃多少天

【样例输入】

5
5 4 3 2 1

【样例输出】

5

题解:
因为要吃最多的天数,所以我们要保证我们选取的这些不连续的区间是严格下降且最长,可以用单调队列维护,复杂度是不靠谱的O(n^2),但是事实证明跑得很快。。也可以跑nlogn的最长严格下降子序列(我想这是正解。。)

Code:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int n,q[100010],ans,t=0;
int in(){
    int x=0; char ch=getchar();
    while (ch<‘0‘ || ch>‘9‘) ch=getchar();
    while (ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();
    return x;
}
int main(){
    n=in(); q[0]=0x7fffffff;
    for (int i=1; i<=n; i++){
        int x=in(),w=t; if (!x) continue;
        while (w>=0){
            if (q[w]==x) break;
            else if (q[w]>x){
                q[++w]=x; t=max(t,w);
                break;
            }
            w--;
        }
        ans=max(ans,w);
    }
    printf("%d\n",ans);
    return 0;
}

【单调队列】【cogs825】【RQNOJ 167】免费午餐

标签:

原文地址:http://blog.csdn.net/morestep/article/details/46051457

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!