前言:把鸽了1个月的博客补上

-----------------

题目链接

题目大意:机器人的灵敏性为$d$。每次可以花费$g$个金币来改造机器人,那么机器人向右跳的范围为$[min(d-g,1),max(d+g,x[n])]$。每个点都有分数$w[i]$。问至少花费多少金币得到分数$k$?

首先,如果用$g$个金币能满足条件,那么$g+1$也能。显然我们要最大值最小,所以我们不妨二分$g$,来求得满足条件的$g$的最小值。

普通的dp应该还是比较好写的。可以拿60pts.

bool check(int g)
{
for (int i=;i<=n;i++) f[i]=-0x3f3f3f3f;f[]=;
int rpos=d+g,lpos=max(d-g,);
for (int i=;i<=n;i++)
{
for (int j=i=;j>=;j--)
{
if (x[i]-x[j]<lpos) continue;
if (x[i]-x[j]>rpos) break;
f[i]=max(f[i],f[j]+w[i]);
if (f[i]>=k) return ;
}
}
return ;
}

对于每一个i,都有一定的可取范围(l,r)。注意到l,r都是单调递增的,且dp方程为$f[i]=max(f[j])+w[i]$,我们可以尝试用单调队列优化。时间复杂度$O(n)$。

bool check(int g)
{
memset(q,,sizeof(q));
memset(f,0x80,sizeof(f));f[]=;
int l=,r=,j=;
int L=d-g,R=d+g;
if (L<) L=;
for (int i=;i<=n;i++)
{
while(x[i]-x[j]>=L&&j<i)
{
if (f[j]!=neInf)//f[j]必须是已经更新过的
{
while(l<=r&&f[q[r]]<=f[j]) r--;//把劣于f[j]的决策排除,因为无论如何都不可能选择它们
q[++r]=j;//入列
}
j++;
}
while(l<=r&&x[i]-x[q[l]]>R) l++;//把不满足条件的排除
if (l<=r) f[i]=f[q[l]]+s[i];//队首一定是最优选择
}
int num=neInf;
for (int i=;i<=n;i++) num=max(num,f[i]);
if (num>=k) return ;
else return ;
}

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const long long neInf=0x8080808080808080;
int f[],n,d,k;
int q[];
int x[],s[],sum,aleft,aright,ans;
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)){if (ch=='-') f=-;ch=getchar();}
while(isdigit(ch)){x=x*+ch-'';ch=getchar();}
return x*f;
}
bool check(int g)
{
memset(q,,sizeof(q));
memset(f,0x80,sizeof(f));f[]=;
int l=,r=,j=;
int L=d-g,R=d+g;
if (L<) L=;
for (int i=;i<=n;i++)
{
while(x[i]-x[j]>=L&&j<i)
{
if (f[j]!=neInf)
{
while(l<=r&&f[q[r]]<=f[j]) r--;
q[++r]=j;
}
j++;
}
while(l<=r&&x[i]-x[q[l]]>R) l++;
if (l<=r) f[i]=f[q[l]]+s[i];
}
int num=neInf;
for (int i=;i<=n;i++) num=max(num,f[i]);
if (num>=k) return ;
else return ;
}
signed main()
{
n=read(),d=read(),k=read();
for (int i=;i<=n;i++)
{
x[i]=read(),s[i]=read();
if (s[i]>) sum+=s[i];
}
aright=max(x[n],d);
if (sum<k){
cout<<-;
return ;
}
while(aleft<=aright)
{
int mid=(aleft+aright)>>;
if (check(mid)) ans=mid,aright=mid-;
else aleft=mid+;
}
cout<<ans;
return ;
}

【NOIP2017】跳房子 题解(单调队列优化线性DP)的更多相关文章

  1. 洛谷luogu3957跳房子(单调队列优化)

    QwQ被普及组的题折磨的死去活来. 硬是卡线段树,没卡过QwQ oi生涯,第一道正经的单调队列dp题 进入正题 题目大意: 其中\(n \le 500000\) 看到这个题的第一感觉就是二分金币数 很 ...

  2. poj1821 Fence【队列优化线性DP】

    Fence Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 6122   Accepted: 1972 Description ...

  3. 洛谷p1725 露琪诺 单调队列优化的DP

    #include <iostream> #include <cstdio> #include <cstring> using namespace std; int ...

  4. 单调队列以及单调队列优化DP

    单调队列定义: 其实单调队列就是一种队列内的元素有单调性的队列,因为其单调性所以经常会被用来维护区间最值或者降低DP的维数已达到降维来减少空间及时间的目的. 单调队列的一般应用: 1.维护区间最值 2 ...

  5. bzoj1855: [Scoi2010]股票交易 单调队列优化dp ||HDU 3401

    这道题就是典型的单调队列优化dp了 很明显状态转移的方式有三种 1.前一天不买不卖: dp[i][j]=max(dp[i-1][j],dp[i][j]) 2.前i-W-1天买进一些股: dp[i][j ...

  6. 【bzoj3831】[Poi2014]Little Bird 单调队列优化dp

    原文地址:http://www.cnblogs.com/GXZlegend/p/6826475.html 题目描述 In the Byteotian Line Forest there are   t ...

  7. BestCoder Round #89 02单调队列优化dp

    1.BestCoder Round #89 2.总结:4个题,只能做A.B,全都靠hack上分.. 01  HDU 5944   水 1.题意:一个字符串,求有多少组字符y,r,x的下标能组成等比数列 ...

  8. [NOIP2017普及组]跳房子(二分,单调队列优化dp)

    [NOIP2017普及组]跳房子 题目描述 跳房子,也叫跳飞机,是一种世界性的儿童游戏,也是中国民间传统的体育游戏之一. 跳房子的游戏规则如下: 在地面上确定一个起点,然后在起点右侧画 nn 个格子, ...

  9. P3957 跳房子(二分答案+单调队列优化DP)

    题目链接:https://www.luogu.org/contestnew/show/4468 题目大意:跳房子,也叫跳飞机,是一种世界性的儿童游戏,也是中国民间传统的体育游戏之一. 跳房子的游戏规则 ...

随机推荐

  1. 在windows中使用labelimg工具搭建图像标注小环境

    文章分成两个部分,第一部分,labelimg工具的安装:第二部分,labelimg工具的使用方法. 第一部分:工具安装 方法一:直接使用网上编译好的Labelimg可执行文件(12.6M),双击执行即 ...

  2. day05总结

    """ echo  "了不起的 [陈少] " 输出结果:   了不起的陈少! ! ! """ ""& ...

  3. ArrayList源码分析-jdk11 (18.9)

    目录 1.概述 2.源码分析 2.1参数 2.2 构造方法 2.2.1 无参构造方法 2.2.2 构造空的具有特定初始容量值方法 2.2.3构造一个包含指定集合元素的列表,按照集合的迭代器返回它们的顺 ...

  4. tinymce 设置和获取编辑器的内容

    $('目标元素').html(插入的内容) //设置tinymce编辑器的内容tinymce.get('目标元素').getContent() //获取tinymce编辑器的内容

  5. VirtualBox安装centos8

    原文链接:https://www.wjcms.net/archives/vagrantbox安装centos8 VirtualBox安装centos8 在线安装(不推荐) 打开git软件,直接运行命令 ...

  6. redis(十一):Redis 列表(List) (python)

    # -*- coding: utf-8 -*- import redis r =redis.Redis(host="123.156.74.190",port=6379,passwo ...

  7. How to use the function of bind

    The usage of  bind  is to define a specified scope for called function. Because the key this is easy ...

  8. day7:字符串的操作/方法&字符串的格式化format&列表的操作

    字符串的相关操作 1.字符串的拼接 strvar = "vegeta"+"ble" print(strvar) # vegetable 2.字符串的重复 str ...

  9. oracle创建Javasource实现数据库备份

    因客户需求,需要在业务系统中,菜单中的网页中的按钮中加入一个按钮,用于点击备份数据库 (环境:只配置了数据源连接oralce ,应用服务器和数据服务器不在一台机器,且数据库机器oracle操作系统账号 ...

  10. SQLite数据库多平台应用及常见错误分析

    SQLite是一个软件库,实现了自给自足的.无服务器的.零配置的.事务性的SQL数据库引擎.SQLite是世界上最广泛部署的数据库引擎之一.SQLite源代码开放,没有授权限制.正是因为其免费.轻巧. ...