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

来源:互联网 发布:用php编辑九九乘法表 编辑:程序博客网 时间:2024/05/20 11:51

825. [RQNOJ 167] 免费午餐

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

【问题描述】

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

【输入文件】

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

【输出文件】

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

【样例输入】

55 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;}
1 0
原创粉丝点击