当前位置: 首页 > news >正文

P3957 [NOIP 2017 普及组] 跳房子

P3957 [NOIP 2017 普及组] 跳房子

题目背景

NOIP2017 普及组 T4

题目描述

跳房子,也叫跳飞机,是一种世界性的儿童游戏,也是中国民间传统的体育游戏之一。

跳房子的游戏规则如下:

在地面上确定一个起点,然后在起点右侧画 nnn 个格子,这些格子都在同一条直线上。每个格子内有一个数字(整数),表示到达这个 格子能得到的分数。玩家第一次从起点开始向右跳,跳到起点右侧的一个格子内。第二次再从当前位置继续向右跳,依此类推。规则规定:

玩家每次都必须跳到当前位置右侧的一个格子内。玩家可以在任意时刻结束游戏,获得的分数为曾经到达过的格子中的数字之和。

现在小 R 研发了一款弹跳机器人来参加这个游戏。但是这个机器人有一个非常严重的缺陷,它每次向右弹跳的距离只能为固定的 ddd。小 R 希望改进他的机器人,如果他花 ggg 个金币改进他的机器人,那么他的机器人灵活性就能增加 ggg,但是需要注意的是,每 次弹跳的距离至少为 111。具体而言,当 g<dg<dg<d 时,他的机器人每次可以选择向右弹跳的距离为 d−g,d−g+1,d−g+2,…,d+g−1,d+gd-g,d-g+1,d-g+2,\ldots,d+g-1,d+gdg,dg+1,dg+2,,d+g1,d+g;否则当 g≥dg \geq dgd 时,他的机器人每次可以选择向右弹跳的距离为 1,2,3,…,d+g−1,d+g1,2,3,\ldots,d+g-1,d+g1,2,3,,d+g1,d+g

现在小 R 希望获得至少 kkk 分,请问他至少要花多少金币来改造他的机器人。

输入格式

第一行三个正整数 n,d,kn,d,kn,d,k,分别表示格子的数目,改进前机器人弹跳的固定距离,以及希望至少获得的分数。相邻两个数 之间用一个空格隔开。

接下来 nnn 行,每行两个整数 xi,six_i,s_ixi,si,分别表示起点到第 iii 个格子的距离以及第 iii 个格子的分数。两个数之间用一个空格隔开。保证 xix_ixi 按递增顺序输入。

输出格式

共一行,一个整数,表示至少要花多少金币来改造他的机器人。若无论如何他都无法获得至少 kkk 分,输出 −1-11

输入输出样例 #1

输入 #1

7 4 10
2 6
5 -3
10 3
11 -3
13 1
17 6
20 2

输出 #1

2

输入输出样例 #2

输入 #2

7 4 20
2 6
5 -3
10 3
11 -3
13 1
17 6
20 2

输出 #2

-1

说明/提示

样例 1 说明

花费 222 个金币改进后,小 R 的机器人依次选择的向右弹跳的距离分别为 $ 2, 3, 5, 3, 4,3$,先后到达的位置分别为 2,5,10,13,17,202, 5, 10, 13, 17, 202,5,10,13,17,20,对应 $ 1, 2, 3, 5, 6, 7$ 这 666 个格子。这些格子中的数字之和 $ 15$ 即为小 R 获得的分数。

样例 2 说明

由于样例中 777 个格子组合的最大可能数字之和只有 181818,所以无论如何都无法获得 202020 分。

数据规模与约定

本题共 10 组测试数据,每组数据等分。

对于全部的数据满足 1≤n≤5×1051 \le n \le 5\times10^51n5×1051≤d≤2×1031 \le d \le2\times10^31d2×1031≤xi,k≤1091 \le x_i, k \le 10^91xi,k109∣si∣<105|s_i| < 10^5si<105

对于第 1,21, 21,2 组测试数据,保证 n≤10n\le 10n10

对于第 3,4,53, 4, 53,4,5 组测试数据,保证 n≤500n \le 500n500

对于第 6,7,86, 7, 86,7,8 组测试数据,保证 d=1d = 1d=1

思路

1.n格子的数目
2.d一次弹跳的距离
3.k是至少要获得的分数(多了当然也可以,不能少),就是跳到格子的数字的和
4.只能往右跳
5.问题:g金币改动弹跳的范围,跳动距离选择面变广,max(d-g,1)<=x<=d+g
6.金币够,能跳任意距离,就能达更多的格子,得到更多的格子和
这单调递增,有序,可以二分找O(logs)
7.有了金币数,跳动范围,就可以算到达每个点的格子和,
f[i]=f[j]+v[i]
双循环就能动态规划算出最大格子和O(n^2),超时
8. 单调队列只留下前序最大格子和,可以O(n)
f[i]=q[l]+v[i]
单调队列降序留存能达i的前序格子和

代码

#include <bits/stdc++.h>
using namespace std;
const int N=5e5+5;//格子数量上限 
const long long inf=1e18; //表示"不可达"的极限值 
struct node{//格子的结构体,没有构造函数,叫聚合类型 int w,//格子距离起点的位置 v;//格子的分数 
}ge[N];//存储所有格子的数组 
int n,//格子总数 d,//机器人初始的固定跳跃距离 k;//目标分数(至少要获得的分数)
long long f[N],//动态规划状态,到达第i个格子时能获得的最大分数 q[N],//单调队列,保持降序,用来找到最大值(到i点的最大分数,源自f[i])。 qw[N],//单调队列,i元素对应的位置,用来判断(单调队列的区间)qw[x]+mind<=i<=qw[x]+maxdhe;//所有格子的最大和(用于判断无解)
bool check(int g){//用来判断,当跳动距离的改动范围是g时,能跳到的格子的和是否>=k int mind=max(1,d-g),maxd=d+g;//mind不是变动范围,而是实际跳跃数,不能是0,否则原地 //机器人从 x 跳到 i,跳跃距离是「i 的位置 - x 的位置」,这个距离必须在 [mind, maxd] 范围内 int l=0,r=-1,//单调队列的首尾指针 x=0;//i的前序,要达i(用来入队,只遍历一次) f[0]=0;//0起点设了就可以 //memset(f,0xcf,sizeof(f));//除了0起点外所有格子都不可达,//memset(f,0,sizeof(f));这样也可以,除了0外其他无所谓,动态规划新得for(int i=1;i<=n;i++){//遍历所有格子,动态规划O(n^2)计算到达该格子的最大分数。//单调队列,能达i点的前序x从队尾入队,替代前面小的格子和,保持队列降序。队首总是最大值,意义在于不二过,O(n) for(;x<=i&&ge[x].w+mind<=ge[i].w;x++){//可达:x的位置+最小跳跃距离<=i的位置(<=x的位置+最大跳跃距离) if(f[x]<=-inf)continue;//-inf表示不可达,不能入队。若入队,再碰到inf的格子,数字上变成可达 while(l<=r&&q[r]<=f[x])r--;//清除小于x的队尾,维护单调队列降序q[++r]=f[x],qw[r]=ge[x].w; //入队。该队列中元素对下个i可能也能用上 } //单调队列清队首不达i的格子,现在用不上往后也用不上 while(l<=r&&qw[l]+maxd<ge[i].w)l++;//超出最大跳跃距离 if(l<=r)f[i]=q[l]+ge[i].v;//动态转移方程。队首q[l]就是能跳到i的最大格子和+i格子数。后面要入队。q是i前的f,f是q算出来的 else f[i]=-inf;//队列没有有效元素,无法跳到i if(f[i]>=k)return 1;}return 0;//做不到 
} 
int main(){//freopen("data.cpp","r",stdin);cin>>n>>d>>k;for(int i=1;i<=n;i++){//0是起点,第一个格子是1 cin>>ge[i].w >>ge[i].v;if(ge[i].v>0)he+=ge[i].v;//累加正分数,用于快速判断无解 }if(he<k){cout<<-1;return 0;}//无解,无法得到k//金币数、跳动距离改动范围越大能选择的格子越多,格子和就越大,正比关系,有序,可以二分 int l=0,r=ge[n].w,m;//查找能跳到的格子的和大于等于(至少)k的跳动距离的改动范围g的最小值,也就是最少金币数while(l<r){//最后重合的位置就是最少的值 m=(l+r)>>1;if(check(m))r=m;//m可行,m上不要 else l=m+1;//不可行,m以左不要//始终在范围内,只是范围缩小了 }cout<<l;//l和r都是满足条件的第一个首元素(至少) return 0;
}

反思

二分要熟悉
动态规划要熟悉
单调队列要熟悉
就这样还有好多细节要处理
真是蜀道难

http://www.dtcms.com/a/515218.html

相关文章:

  • 日语学习-日语知识点小记-构建基础-JLPT-N3阶段-二阶段(6):文法運用
  • 【数据结构入坑指南】--《层序分明:堆的实现、排序与TOP-K问题一站式攻克(源码实战)》
  • 做网站的公司怎么推销湘潭做网站价格 q磐石网络
  • 用Python Streamlit sqlite3 写一个简单博客
  • 微型计算机接口与原理笔记
  • 大学生免费ppt网站广州分销商城开发
  • 良策金宝AI定制方案:构建企业专属的“工程智能体”
  • docker 容器web站点 中文文件名访问404问题
  • 【第五章:计算机视觉-项目实战之推荐/广告系统】2.粗排算法-(1)粗排用来干什么?“我大体筛一下“
  • FDAbench-Full 数据代理任务基准:Python 使用路径
  • HarmonyOS之启动应用内的UIAbility组件
  • 【开题答辩全过程】以抖音热点与可视化分析为例,包含答辩的问题和答案
  • SONiC控制面 + VPP数据面:AsterNOS-VPP的高性能开放之路
  • 未来之窗昭和仙君(二十八)商业收银开发音频播放——东方仙盟筑基期
  • 自助网站系统上海网站建设公司网站建设
  • 杭州网站设计推荐柚米莆田做外贸网站
  • Rust 枚举类详解
  • UU远程——让工作、学习、娱乐跨设备无缝衔接,“远程”更像“身边”
  • 关于模型结构与参数的文件类型及运行设备
  • 一种基于STL-LSTM混合模型的低轨卫星钟差短期预报方法
  • 【Docker】[特殊字符] Docker 部署完全指南 - 从本地开发到云服务器
  • 宝塔面板部署Django:使用Unix Socket套接字通信的完整教程(附核心配置与问题排查)
  • 广西建设局建设行政主管部网站资源网站优化排名软件公司
  • 基于Vue的2025年哈尔滨亚冬会志愿者管理系统5zqg6m36(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
  • 软件可用性测试历史概念✅软件可用性测试的国际标准✅软件可用性测试方法
  • 深入 JavaScript 对象与代理模式的本质、应用与区别!
  • 响水网站制作公司平顺网站建设
  • 顺昌网站建设临沂网站制作公司
  • Llama-2-7b 昇腾 NPU 测评总结:核心性能数据、场景适配建议与硬件选型参考
  • 奥威BI:AI数据分析赋能企业智能决策