zoukankan      html  css  js  c++  java
  • 【P3957】跳房子(单调队列+DP+二分)

    终于把这个题缸出来了,话说这题也不是想的那么难。。。

    因为最小的最大,所以二分,因为由前面推出后面,所以DP,因为输入单调,朴素DP会T,所以单调队列。要注意的是,这个题数据很大,要开LL,然后DP数组每次要清为一个大负值,因为输入中有负值。然后单调队列的使用还是有些清奇的地方,待会看代码吧。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #define re register
    #define ll long long
    #define mo 2015
    using namespace std;
    long long n,dis,k;
    long long ans,m,cnt,tot,d[5000001],maxd,cost,l,r,flag,leftt,rightt;
    long long s[5000001],f[1000001];
    ll q[2000001],head,tail;
    long long maxx;
    inline bool check(int x)
    {
        for(re int i=1;i<=n;i++) f[i]=-1e12;
        memset(q,0,sizeof(q));
        head=1;tail=0;
        leftt=max(dis-x,(ll)1);
        rightt=dis+x;
        int p=0;
        for(re int i=1;i<=n;i++)
        {
            while(d[i]-d[p]>=leftt&&p<i)
            {
                while(head<=tail&&f[p]>=f[q[tail]])
                tail--;
                q[++tail]=p;
                p++;
            }
            while(head<=tail&&d[i]-d[q[head]]>dis+x)
            head++;
            if(head>tail)
            continue;
            f[i]=s[i]+f[q[head]];
            if(f[i]>=k)
            return 1;
        }
        return 0;
    }
    int main()
    {
        cin>>n>>dis>>k;
        for(re int i=1;i<=n;i++)
        {
            cin>>d[i]>>s[i];
        }
        int l=0,r=100000001;
        while(l<=r)
        {
            int mid=l+r>>1;
            if(check(mid))
            {
                r=mid-1;
            }else
            l=mid+1;
        }
        cout<<l;
        return 0;
    }
  • 相关阅读:
    protected、public、private
    第十五章 面向对象程序设计
    第十四章 重载运算与类型转换
    聚合类
    explicit构造函数
    allocator类
    直接管理内存——new和delete
    智能指针
    Bugku-CTF之点击一百万次
    Bugku-CTF之flag在index里
  • 原文地址:https://www.cnblogs.com/victorique/p/8426979.html
Copyright © 2011-2022 走看看