zoukankan      html  css  js  c++  java
  • 洛谷 3957 跳房子——二分答案+单调队列

    题目:https://www.luogu.org/problemnew/show/P3957

    二分答案以后可以dp求最优解,转移就是一个滑动窗口,所以用单调队列。

    上午想好开 long long ,下午来了又忘了。到手的1A飞了。

    但其实觉得很奇怪,因为一个 <k (<1e9)的数加一个s(<=1e5)怎么会爆 int ?

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int N=5e5+5;
    int n,D,lm,x[N],c[N],ans=-1,q[N],he,tl;
    ll dp[N];
    int rdn()
    {
      int ret=0;bool fx=1;char ch=getchar();
      while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}
      while(ch>='0'&&ch<='9') ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar();
      return fx?ret:-ret;
    }
    bool solve(int l,int r)
    {
      memset(dp,-2,sizeof dp); dp[0]=0;
      he=1;tl=0;q[0]=-1;
      for(int i=1;i<=n;i++)
        {
          while(x[i]-x[q[tl]+1]>=l)
        {
          int d=q[tl]+1;
          while(he<=tl&&dp[d]>dp[q[tl]])tl--;
          q[++tl]=d;
        }
          while(he<=tl&&x[i]-x[q[he]]>r)he++;
          if(he>tl)continue;
          dp[i]=dp[q[he]]+c[i];
          if(dp[i]>=lm)return true;
        }
      return false;
    }
    int main()
    {
      n=rdn(); D=rdn(); lm=rdn();
      for(int i=1;i<=n;i++)x[i]=rdn(),c[i]=rdn();
      int l=0,r=max(D-1,x[n]-D);
      while(l<=r)
        {
          int mid=l+r>>1;
          if(solve(max(1,D-mid),D+mid))ans=mid,r=mid-1;
          else l=mid+1;
        }
      printf("%d
    ",ans);
    }
  • 相关阅读:
    第一章 002-JDK的安装
    第一章 001-初识Java
    计算2^4000内数字0到9的分布
    1027 大数乘法
    1005 大数加法
    哈夫曼编码
    new: Set up a window
    GLFW扩展库
    outdated: 3.Adding Color
    简单的图元
  • 原文地址:https://www.cnblogs.com/Narh/p/9862254.html
Copyright © 2011-2022 走看看