升降梯上——玄学dp
升降梯上
题目描述
开启了升降梯的动力之后,探险队员们进入了升降梯运行的那条竖直的隧道,映入眼帘的是一条直通塔顶的轨道、一辆停在轨道底部的电梯、和电梯内一杆控制电梯升降的巨大手柄。
\(Nescafe\) 之塔一共有N层,升降梯在每层都有一个停靠点。手柄有M个控制槽,第i个控制槽旁边标着一个数 \(C_i\),满足 \(C_1<C_2<C_3<……<C_M\)。如果 \(C_i>0\),表示手柄扳动到该槽时,电梯将上升 \(C_i\) 层;如果 \(C_i<0\),表示手柄扳动到该槽时,电梯将下降 \(-C_i\) 层;并且一定存在一个 \(C_i=0\),手柄最初就位于此槽中。注意升降梯只能在 \(1-N\) 层间移动,因此扳动到使升降梯移动到 \(1\) 层以下、\(N\) 层以上的控制槽是不允许的。
电梯每移动一层,需要花费 \(2\) 秒钟时间,而手柄从一个控制槽扳到相邻的槽,需要花费 \(1\) 秒钟时间。探险队员现在在 \(1\) 层,并且想尽快到达 \(N\) 层,他们想知道从 \(1\) 层到 \(N\) 层至少需要多长时间?
输入格式
第一行两个正整数 \(N\)、\(M\)。
第二行M个整数 \(C_1\)、\(C_2……C_M\)。
输出格式
输出一个整数表示答案,即至少需要多长时间。若不可能到达输出 \(-1\)。
样例
样例输入
6 3
-1 0 2
样例输出
19
数据范围与提示
手柄从第二个槽扳到第三个槽(\(0\) 扳到 \(2\)),用时 \(1\) 秒,电梯上升到 \(3\) 层,用时 \(4\) 秒。
手柄在第三个槽不动,电梯再上升到 \(5\) 层,用时 \(4\) 秒。
手柄扳动到第一个槽(\(2\) 扳到 \(-1\)),用时 \(2\) 秒,电梯下降到 \(4\) 层,用时 \(2\) 秒。
手柄扳动到第三个槽(\(-1\) 扳倒 \(2\)),用时 \(2\) 秒,电梯上升到 \(6\) 层,用时 \(4\) 秒。
总用时为 \((1+4)+4+(2+2)+(2+4)=19\) 秒。
对于 \(30\%\) 的数据,满足 \(1\leq N\leq 10,2\leq M\leq 5\)。
对于 \(100\%\) 的数据,满足 \(1\leq N\leq 1000,2\leq M\leq 20,-N<C_1<C_2<……<C_M<N\)。
思路
这个题做法很多,本博主只讲其中 \(dp\) 的玄学做法,若想看最短路,\(Dfs\)等做法,出门右转。
首先我们可以定义一个 \(dp[i][j]\),表示当手柄在第 \(i\) 的位置时,走到了第 \(j\) 层。
我们上一个状态不能确定到底是在哪个手柄,所以要挨个枚举一遍。
时间加上移动手柄的时间和升降梯移动的时间,去最小值即可。
动态转移方程:
if(i==k){//这个判断加不加都可
dp[i][j]=min(dp[k][j-c[i]]+abs(c[i])*2,dp[i][j]);
}else{
dp[i][j]=min(dp[k][j-c[i]]+abs(i-k)+abs(c[i])*2,dp[i][j]);
}
思路很好想,但是实现时会发现仅进行一遍,有些点并没有更新。
所以我们进行多次 \(dp\),发现到第 \(4\) 次时,所有的值都进行了更新,而且不再改变。
若我们在一次 \(dp\) 中,正反都进行一遍,只需 \(3\) 次即可。
若只正向进行,所需的次数就很玄学,保险起见直接 \(20\) 次。
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn=1000+50,INF=0x3f3f3f3f;
int n,m;
int x0;
int c[maxn];
int dp[50][maxn];
int ans=INF;
bool cmp(int a,int b){
return a>b;
}
int main(){
memset(dp,0x3f,sizeof(dp));//初始为最大
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d",&c[i]);
if(c[i]==0){
x0=i;//找到手柄的起始点
}
}
for(int i=1;i<=m;i++){
dp[i][1]=abs(i-x0);//初始化
}
dp[x0][1]=0;//初始化
for(int s=1;s<=20;s++){//保险20次
for(int i=1;i<=m;i++){//当前状态
for(int j=2;j<=n;j++){//当前层数
for(int k=1;k<=m;k++){//上一个状态
if(j-c[i]<=0||j-c[i]>n)continue;//若上一个状态越界,直接跳过
if(i==k){//可省略判断
dp[i][j]=min(dp[k][j-c[i]]+abs(c[i])*2,dp[i][j]);
}else{
dp[i][j]=min(dp[k][j-c[i]]+abs(i-k)+abs(c[i])*2,dp[i][j]);
}
}
}
}
}
for(int i=1;i<=m;i++){
ans=min(ans,dp[i][n]);
}
if(ans==INF){
printf("-1\n");
}else{
printf("%d\n",ans);
}
return 0;
}
升降梯上——玄学dp的更多相关文章
- ZOJ1232 Adventure of Super Mario spfa上的dp
很早之前听说有一种dp是在图上的dp,然后是在跑SPFA的时候进行dp,所以特地找了一题关于在SPFA的时候dp的. 题意:1~a是村庄 a+1~a+b是城堡,存在m条无向边.求由a+b->1的 ...
- UVA - 10131Is Bigger Smarter?(DAG上的DP)
题目:UVA - 10131Is Bigger Smarter? (DAG) 题目大意:给出一群大象的体重和IQ.要求挑选最多的大象,组成一个序列.严格的体重递增,IQ递减的序列.输出最多的大象数目和 ...
- BZOJ 3998 TJOI2015 弦论 后缀自动机+DAG上的dp
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3998 题意概述:对于一个给定长度为N的字符串,求它的第K小子串是什么,T为0则表示不同位置 ...
- 区间和序列上的dp
区间上的dp状态设计最基本的形式: \(F[i]\)表示以i结尾的最优值或方案数. \(F[i][k]\)表示以i结尾附加信息为k的最优值或方案数. 当然可以有多维附加信息. 转移的话往往是枚举上一个 ...
- [Tyvj2032]升降梯上(最短路)
[Tyvj2032]升降梯上 Description 开启了升降梯的动力之后,探险队员们进入了升降梯运行的那条竖直的隧道,映入眼帘的是一条直通塔顶的轨道.一辆停在轨道底部的电梯.和电梯内一杆控制电梯升 ...
- TYVJ2032 「Poetize9」升降梯上
P2032 「Poetize9」升降梯上 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 开启了升降梯的动力之后,探险队员们进入了升降梯运行的那条竖直的隧道, ...
- [tyvj2032]升降梯上<dp&spfa>
题目背景 开启了升降梯的动力之后,探险队员们进入了升降梯运行的那条竖直的隧道,映入眼帘的是一条直通塔顶的轨道.一辆停在轨道底部的电梯.和电梯内一杆控制电梯升降的巨大手柄. 题目描述 Nescafe 之 ...
- poj上的dp专题
更新中... http://poj.org/problem?id=1037 dp[i][j][0]表示序列长度为i,以j开始并且前两位下降的合法序列数目; dp[i][j][1]表示序列长度为i, 以 ...
- UVA1099----Sharing Chocolate----在集合上的DP
题目地址:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
随机推荐
- java实现第五届蓝桥杯猜字母
猜字母 题目描述 把abcd-s共19个字母组成的序列重复拼接106次,得到长度为2014的串. 接下来删除第1个字母(即开头的字母a),以及第3个,第5个等所有奇数位置的字母. 得到的新串再进行删除 ...
- 2018年全国多校算法寒假训练营练习比赛(第二场)H-了断局
题目描述 既然是了断局了,大家就随便玩玩数字呗.已知一个数列前十项分别是{0, 1, 1, 2, 4, 7, 13, 24, 44, 81},小G不满足呀:我要更多的数!!!不给就不让你们玩了.小G会 ...
- 在树莓派3b or 3a or 4a or 4b上搭建OpenWebRX
OpenWebRx OpenWebRX 项目提供了搭建WebSDR的解决方案,该项目基于 Python 编写,除了完全开源外,官方还提供了完备的技术文档.您只需要一台电脑或是树莓派,一个SDR设备和网 ...
- (九)不安全的HTTP方法
01 漏洞描述 <HTTP | HTTP报文>中介绍了HTTP的请求方法.在这些方法中,HTTP定义了一组被称为安全方法的方法:GET.HEAD.OPTIONS.TRACE,这些方法不会产 ...
- [C#.NET 拾遗补漏]03:你可能不知道的几种对象初始化方式
阅读本文大概需要 1.2 分钟. 随着 C# 的升级,C# 在语法上对对象的初始化做了不少简化,来看看有没有你不知道的. 数组的初始化 在上一篇罗列数组的小知识的时候,其中也提到了数组的初始化,这时直 ...
- MongoDB知识点总结
一:MongoDB 概述 一.NoSQL 简介 1. 概念:NoSQL(Not Only SQL的缩写),指的是非关系型数据库,是对不同于传统的关系型数据库的数据库管理系统的统称.用于超大规模数 ...
- SQL Beautifier & SQL2014自带的格式化工具
格式化工具(希望有几款集成在IDE中的格式化工具)为什么要说明这些,不是为说明这个工具而发,看到那几千行或集成在一起的存储过程觉得乱七八的不爽,后面将会强力训练下自己. --下面这款SQL Beaut ...
- MQ系列(1)——rabbitMQ简介
前文我们学习了 MQ的相关知识,现在我们来学习一下实现了AMQP协议的 rabbitMQ 中间件.rabbitMQ 是使用 erlang 语言编写的中间件(erlang之父 19年4月去世的,很伟大一 ...
- 循序渐进VUE+Element 前端应用开发(11)--- 图标的维护和使用
在VUE+Element 前端应用中,图标是必不可少点缀界面的元素,因此整合一些常用的图标是非常必要的,还好Element界面组件里面提供了很多常见的图标,不过数量不是很多,应该是300个左右吧,因此 ...
- Andrew Ng - 深度学习工程师 - Part 1. 神经网络和深度学习(Week 1. 深度学习概论)
=================第1周 循环序列模型=============== ===1.1 欢迎来到深度学习工程师微专业=== 我希望可以培养成千上万的人使用人工智能,去解决真实世界的实际问 ...