zoukankan      html  css  js  c++  java
  • bzoj 1314: River过河 优先队列

    1314: River过河

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 26  Solved: 10
    [Submit][Status][Discuss]

    Description

    ZY 带N个小Kid过河,小KID分成两种:高一年级,高二年级,由于存在代沟问题,如果同一条船上高一年级生和高二年级生数量之差超过K,就会发生不和谐的 事件.当然如果一条船上全是同一年级的,就绝对不会发生争执.现在ZY按小KID队列的顺序依次安排上船,并且不能让他们在过河时发生争执.对于当前等待 上船的小KID来说,要么让他上船,要么将停在渡口的船开走,再让他上另一条船,同一条船上的人不过超过M人.为了让所有的小KID过河,在知悉小KID 队列的情况下,最少需要多少条船.

    Input

    第一行给出N,M,K.含义如上所述 下行N行用来描述小KID的队列,每行一个字符”A”或者”L”

    Output

    最少需要多少条船

    Sample Input

    5 4 1
    A
    L
    L
    L
    A

    Sample Output

    2

    HINT

    前三个人一条船,后两个人一条船
    数据范围
    30% 数据中1<=N<=1000
    100%数据中1<=N<=250000,1<=M,K<=N

      这道题过的人这么少不太正常啊。

      容易看出,如果对输入数列换成+1/-1,然后做前缀和,当前dp[i]可以由j-i>=m and abs(a[j]-a[i])<=k 一个矩形内区域的dp值转移出来,首先kdtree肯定没有问题,看有无简单点的做法,思考整体二分,发现不太好处理,注意上述的矩形区域有着固定的宽,而且x坐标单调递增,于是很容易想到对于每一个a[i]维护优先队列了。

      用deque<int>要mle,原因是deque封装了大量维护下标访问的量,而改成list<int>内存要好很多。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<deque>
    #include<list>
    using namespace std;
    #define MAXN 251000
    #define lch (now<<1)
    #define rch (now<<1^1)
    #define smid ((l+r)>>1)
    #define MAXT MAXN*4
    #define INF 0x3f3f3f3f
    int a[MAXN];
    int dp[MAXN];
    list<int> lst[MAXN];
    int sgt[MAXT];
    void Modify_sgt(int now,int l,int r,int pos,int v)
    {
            if (l==r)
            {
                    sgt[now]=v;
                    return ;
            }
            if (pos<=smid)
                    Modify_sgt(lch,l,smid,pos,v);
            else
                    Modify_sgt(rch,smid+1,r,pos,v);
            sgt[now]=min(sgt[lch],sgt[rch]);
    }
    int Query_sgt(int now,int l,int r,int x,int y)
    {
            if (l==x && r==y)
                    return sgt[now];
            if (y<=smid)
                    return Query_sgt(lch,l,smid,x,y);
            else if (smid<x)
                    return Query_sgt(rch,smid+1,r,x,y);
            else
                    return min(Query_sgt(lch,l,smid,x,smid),Query_sgt(rch,smid+1,r,smid+1,y));
    }
    list<int> que;
    
    int main()
    {
            freopen("input.txt","r",stdin);
            int n,m,t,x,y,z;
            scanf("%d%d%d
    ",&n,&m,&t);
            char ch;
            int level=0;
            int mxvvv=0;
            memset(sgt,INF,sizeof(sgt));
            a[0]=0;
            for (int i=1;i<=n;i++)
            {
                    scanf("%c
    ",&ch);
                    if (ch=='A')
                            a[i]=1;
                    else
                            a[i]=-1;
            }
            for (int i=1;i<=n;i++)
                    a[i]+=a[i-1];
            for (int i=0;i<=n;i++)
                    level=min(a[i],level);
            for (int i=0;i<=n;i++)
                    mxvvv=max(a[i],mxvvv);
            level=-level;
            mxvvv+=level;
            for (int i=0;i<=n;i++)
                    a[i]+=level;
            dp[0]=0;
            lst[a[0]].push_back(0);
            Modify_sgt(1,0,mxvvv,a[0],dp[lst[a[0]].front()]);
            que.push_back(1);
            for (int i=1;i<=n;i++)
            {
                    dp[i]=Query_sgt(1,0,mxvvv,max(0,a[i]-t),min(mxvvv,a[i]+t))+1;
                    if (que.size() && a[que.front()]-a[que.front()-1]==a[i]-a[i-1])
                            dp[i]=min(dp[i],dp[que.front()-1]+1);
                    while (lst[a[i]].size() && dp[lst[a[i]].back()]>=dp[i])
                            lst[a[i]].pop_back();
                    lst[a[i]].push_back(i);
                    Modify_sgt(1,0,mxvvv,a[i],dp[lst[a[i]].front()]);
                    if (i>=m)
                    {
                            if (lst[a[i-m]].size() && lst[a[i-m]].front()==i-m)
                            {
                                    lst[a[i-m]].pop_front();
                                    if (lst[a[i-m]].size())
                                            Modify_sgt(1,0,mxvvv,a[i-m],dp[lst[a[i-m]].front()]);
                                    else
                                            Modify_sgt(1,0,mxvvv,a[i-m],INF);
                            }
                    }
                    if (i==1 || a[i]-a[i-1]==a[i+1]-a[i])
                    {
                            while (!que.empty() && dp[que.back()-1]>=dp[i])
                                    que.pop_back();
                            que.push_back(i+1);
                    }else
                    {
                            while (!que.empty())
                                    que.pop_back();
                            que.push_back(i+1);
                    }
                    if (i-que.front()+1>=m)
                            que.pop_front();
            }
            printf("%d
    ",dp[n]);
    }
  • 相关阅读:
    博客园.netCore+阿里云服务器升级中会报的一个错误
    框架资料整理
    免费在线作图,实时协作-工具
    ubuntu14.04 配置网络
    vagrant的学习 之 基础学习
    mysql 定时任务
    linux 命令练习 2018-08-27
    一点一滴(一)
    Thinkphp5.0 的实践一
    Thinkphp5.0 的使用模型Model的获取器与修改器
  • 原文地址:https://www.cnblogs.com/mhy12345/p/4567088.html
Copyright © 2011-2022 走看看