Luogu P3957 跳房子
题面
跳房子,也叫跳飞机,是一种世界性儿童游戏,也是中国民间传统的体育游戏之一。
跳房子的游戏规则如下:
在地面上确定一个起点,然后在起点右侧画 n 个格子,这些格子都在同一条直线上。每个格子内有一个数字( 整数),表示到达这个格子能得到的分数。玩家第一次从起点开始向右跳, 跳到起点右侧的一个格子内。第二次再从当前位置继续向右跳,依此类推。
规则规定玩家每次都必须跳到当前位置右侧的一个格子内。玩家可以在任意时刻结束游戏,获得的分数为曾经到达过的格子中的数字之和。
现在小 R 研发了一款弹跳机器人来参加这个游戏。但是这个机器人有一个非常严重的缺陷,它每次向右弹跳的距离只能为固定的 d。小 R 希望改进他的机器人,如果他花 g 个金币改进他的机器人,那么他的机器人灵活性就能增加 g, 但是需要注意的是,每次弹 跳的距离至少为 1。 具体而言, 当g < d时, 他的机器人每次可以选择向右弹跳的距离为 d-g,d-g+1,d-g+2, …,d+g-2,d+g-1,d+g; 否则(当g ≥ d时),他的机器人每次可以选择向右弹跳的距离为1,2,3, …, d+g-2,d+g-1,d+g。
现在小 R 希望获得至少 k 分,请问他至少要花多少金币来改造他的机器人。
输入输出格式
输入格式
第一行三个正整数 n , d ,k,分别表示格子的数目,改进前机器人弹跳的固定距离,以及希望至少获得的分数。相邻两个数 之间用一个空格隔开。
接下来n行,每行两个正整数x_i,s_i ,分别表示起点到第 i 个格子的距离以及第 i 个格子的分数。两个数之间用一个空格隔开。保证 x_i 按递增顺序输入。
输出格式
一行,一个整数,表示至少要花多少金币来改造他的机器人。若无论如何他都无法获得至少 k分,输出 −1 。
思路
根据题意易得dp方程为f[i]=max(f[i-k...i])+s[i];
~~易得题解~~
//你发现了一个比标算还快的错误解法
#include<bits/stdc++.h>
using namespace std;
int n,d,k,ans;
long long x[500005],s[500005],f[500005];
bool check(int g)
{
int maxl=max(d-g,1);
int maxr=d+g;
memset(f,-127,sizeof(f));
f[0]=0;
for (int i=1;i<=n;i++)
{
for (int j=i-1;j>=0;j--)
{
if (x[i]-x[j]<maxl) continue;
if (x[i]-x[j]>maxr) break;
f[i]=max(f[i],f[j]+s[i]);
if (f[i]>=k) return 1;
}
}
return 0;
}
int main()
{
cin>>n>>d>>k;
for (int i=1;i<=n;i++) cin>>x[i]>>s[i];
int l=0,r=200005;
while(l<=r)
{
int mid=(l+r)/2;
if (check(mid)) ans=mid,r=mid-1;
else l=mid+1;
}
cout<<ans<<endl;
return 0;
}
我们知道这样是肯定过不了的,所以要想办法优化。这时我想到了单调队列的优化------*既然我们在转移中要求f[i-k...i]的最大值,那为什么不先用一个单调队列存起来然后O(1)调用呢?*
然后......题解就出来了。
注意点:过期的数(走不过来)就pop,记得开个top表示队列顶,要好做的多。
啥?为什么存编号?方便调用以及判断啊。
#include<bits/stdc++.h>
#define INF 9999999999
using namespace std;
deque<long long>q;
int n,d,k,ans=INF;
long long x[500005],s[500005],f[500005];
bool check(int g)
{
while(!q.empty()) q.pop_back();
int maxl=max(d-g,1);
int maxr=d+g;
memset(f,0,sizeof(f));
x[0]=0;
int top=0;
for (int i=1;i<=n;i++)
{
while(x[i]>=maxl+x[top])
{
while(!q.empty()&&f[top]>=f[q.back()]) q.pop_back();
q.push_back(top);
top++;
//puts("RUN");
}
while (!q.empty()&&x[i]-x[q.front()]>maxr) q.pop_front();
if (q.empty()) f[i]=-INF;
else f[i]=f[q.front()]+s[i];
if (f[i]>=k) return 1;
}
return 0;
}
int main()
{
cin>>n>>d>>k;
for (int i=1;i<=n;i++) cin>>x[i]>>s[i];
int l=0,r=2000005;
while(l<=r)
{
int mid=(l+r)>>1;
if (check(mid)) ans=mid,r=mid-1;
else l=mid+1;
}
if (ans!=INF) cout<<ans<<endl;else cout<<-1<<endl;
return 0;
}
Luogu P3957 跳房子的更多相关文章
- P3957 跳房子(二分答案+单调队列优化DP)
题目链接:https://www.luogu.org/contestnew/show/4468 题目大意:跳房子,也叫跳飞机,是一种世界性的儿童游戏,也是中国民间传统的体育游戏之一. 跳房子的游戏规则 ...
- 洛谷 P3957 跳房子
https://www.luogu.org/problemnew/show/P3957 错误记录:1.没开longlong 2. -inf不够小 #include<cstdio> #inc ...
- 洛谷 P3957 跳房子 —— 二分答案+单调队列优化DP
题目:https://www.luogu.org/problemnew/show/P3957 先二分一个 g,然后判断: 由于转移的范围是一个区间,也就是滑动窗口,所以单调队列优化: 可以先令队尾为 ...
- 洛谷P3957 跳房子 题解 二分答案/DP/RMQ
题目链接:https://www.luogu.org/problem/P3957 这道题目我用到了如下算法: 线段树求区间最大值: 二分答案: DP求每一次枚举答案g时是否能够找到 \(\ge k\) ...
- P3957 跳房子
题目描述 跳房子,也叫跳飞机,是一种世界性的儿童游戏,也是中国民间传统的体育游戏之一. 跳房子的游戏规则如下: 在地面上确定一个起点,然后在起点右侧画 n 个格子,这些格子都在同一条直线上.每个格子内 ...
- 洛谷P3957 跳房子(Noip2017普及组 T4)
今天我们的考试就考到了这道题,在考场上就压根没有思路,我知道它是一道dp的题,但因为太弱还是写不出来. 下来评讲的时候知道了一些思路,是dp加上二分查找的方式,还能够用单调队列优化. 但看了网上的许多 ...
- 洛谷P3957 跳房子
普及组的题.....填坑来了. 当年的我一眼二分+DP,现在都佩服起自己来了...... 然后我们就写个二分,在check里面写单调队列优化DP即可. 然后就A了...... #include < ...
- [luogu 3957]跳房子
题目链接 50分做法 挺显然的一个做法,因为金币量是单调的(如果你花i枚金币可以得到最优解,i+1枚也一定可以),所以可以二分答案 然后对于二分出来的每个答案,都做一遍dp,效率$O(n^2logn) ...
- 2018.09.26洛谷P3957 跳房子(二分+单调队列优化dp)
传送门 表示去年考普及组的时候失了智,现在看来并不是很难啊. 直接二分答案然后单调队列优化dp检验就行了. 注意入队和出队的条件. 代码: #include<bits/stdc++.h> ...
随机推荐
- MT【175】刚刚凑巧
已知$\Delta ABC$满足$\sin^2A+\sin^2B+\sin^2C=2\sqrt{3}\sin A\sin B\sin C,a=2$,求$A$ 提示:利用正弦定理:$a^2+b^2+c^ ...
- 洛谷P3380 【模板】二逼平衡树(树套树,树状数组,线段树)
洛谷题目传送门 emm...题目名写了个平衡树,但是这道题的理论复杂度最优解应该还是树状数组套值域线段树吧. 就像dynamic ranking那样(蒟蒻的Sol,放一个link骗访问量233) 所有 ...
- 【题解】 Codeforces 662A Gambling Nim (线性基)
662A,戳我戳我 Solution: 我们先取\(ans=a[1] \bigoplus a[2] \bigoplus ... \bigoplus a[n]\),然后我们定义\(c[i]=a[i] \ ...
- 【题解】 [SCOI2010]连续攻击游戏 (二分图匹配)
原题目戳我 Solution: 方法很巧妙,我们把每个装备的属性 与 装备编号连起来 从1-10000跑二分图,如果出现断层,就退出,输出答案就好. memset清理bool快一点,int洛谷上超时了 ...
- JDK 目录结构
c:\jdk1.7.0: JDK软件安装根目录.包含版权,许可证和自述文件等. c:\jdk1.7.0\bin: 包含JDK中开发工具的可执行文件(在PATH环境变量中应该包含此目录). c:\jdk ...
- maven 整合支付宝,导入alipay-sdk-java包到本地仓库
maven 整合支付宝,导入alipay-sdk-java包到本地仓库 1.环境变量添加: MAVEN_HOME:(maven位置) M2_HOME:(maven位置) PATH:%M2_HOME ...
- Chart Controls 简介与下载
虽然博客园已有人介绍过了,还是忍不住介绍一下微软这套免费又功能强大的图表控件「Microsoft Chart Controls for Microsoft .NET Framework 3.5」.本帖 ...
- Solr记录-solr检索和查询数据
Solr检索数据 在本章中,我们将讨论如何使用Java Client API检索数据.假设有一个名为sample.csv的.csv文档,其中包含以下内容. 001,9848022337,Hyderab ...
- Spring MVC 中 @ModelAttribute 注解的妙用
Spring MVC 中 @ModelAttribute 注解的妙用 Spring MVC 提供的这种基于注释的编程模型,极大的简化了 web 应用的开发.其中 @Controller 和 @Rest ...
- 你真的理解js的赋值语句么
之前谢亮兄和我一起讨论的一个问题: var a = {}; a.x = a = 3; a 的值是什么. 其实当执行赋值语句的时候,js 的 = 左侧不是原始变量地址,而是一个新值.怎么理解这句话呢? ...