CodeForces1249E-By Elevator or Stairs?-好理解自己想不出来的dp
Input
The first line of the input contains two integers nn and cc (2≤n≤2⋅105,1≤c≤10002≤n≤2⋅105,1≤c≤1000) — the number of floors in the building and the time overhead for the elevator rides.
The second line of the input contains n−1n−1 integers a1,a2,…,an−1a1,a2,…,an−1 (1≤ai≤10001≤ai≤1000), where aiai is the time required to go from the ii-th floor to the (i+1)(i+1)-th one (and from the (i+1)(i+1)-th to the ii-th as well) using the stairs.
The third line of the input contains n−1n−1 integers b1,b2,…,bn−1b1,b2,…,bn−1 (1≤bi≤10001≤bi≤1000), where bibi is the time required to go from the ii-th floor to the (i+1)(i+1)-th one (and from the (i+1)(i+1)-th to the ii-th as well) using the elevator.
Output
Print nn integers t1,t2,…,tnt1,t2,…,tn, where titi is the minimum total time to reach the ii-th floor from the first floor if you can perform as many moves as you want.
Examples
10 2
7 6 18 6 16 18 1 17 17
6 9 3 10 9 1 10 1 5
0 7 13 18 24 35 36 37 40 45
10 1
3 2 3 1 3 3 1 4 1
1 2 3 4 4 1 2 1 3
0 2 4 7 8 11 13 14 16 17 题意:
给出n、c,表示有n层楼,等电梯需要c时间;
给出两行数,每行有n-1个数,
第一行stairs代表从1楼到每层楼走楼梯需要的时间
第二行elevator代表从1楼到每层楼乘电梯需要的时间;
需要注意的是,从电梯转电梯不需要等待时间,从楼梯转楼梯也不需要等待时间,
但是从楼梯转电梯需要算上等待的时间 t 。
求:
从1楼到每层楼所需的最短时间,输出应该有n-1个时间。 思路:
由于存在两种状态,所以可以用0代表乘电梯,1代表走楼梯;
所以一开始可以按照题目所给的开一个三维数组dp [ i ] [ j ] [ k ],i代表乘电梯还是走楼梯,j代表当前到达第几层,k代表将要去第几层。
所以一开始进行dp清空
接下来赋初值,由于不知道从1楼往上走是等电梯还是走楼梯,所以假设等电梯的话需要赋初值dp=c,算上等电梯的时间。
初始化如下:
memset(dp,0,sizeof(dp));
dp[][][]=c;//电梯来电梯走,需要等电梯
dp[][][]=c;//电梯来楼梯走,需要等电梯
dp[][][]=;//楼梯来电梯走
dp[][][]=;//楼梯来楼梯走
之后不管是走楼梯还是乘电梯都需要加上楼梯到楼梯或者电梯到电梯转的时间。如果碰到楼梯转电梯的情况,加上c即可。
动态转移方程如下:
dp[i][][]=min(dp[i-][][]+b[i-],dp[i-][][]+b[i-]+c);
dp[i][][]=min(dp[i-][][]+b[i-],dp[i-][][]+b[i-]+c);
dp[i][][]=min(dp[i-][][]+a[i-],dp[i-][][]+a[i-]);
dp[i][][]=min(dp[i-][][]+a[i-],dp[i-][][]+a[i-]);
三维代码:
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
const int N=2e5+; int a[N],b[N];
int dp[N][][]; //dp[i][j][k] 到达第几层,j来,k走
//0电梯 1楼梯
int main()
{
int n,c;
while(~scanf("%d %d",&n,&c))
{
memset(dp,,sizeof(dp));
// for(int i=2;i<=n;i++)//0 7 13 18 24 35 36 37 40 45
// wa 0 0 7 13 18 24 35 36 37 40
for(int i=; i<n; i++)
scanf("%d",&a[i]);//楼梯1
for(int i=; i<n; i++)
scanf("%d",&b[i]);//电梯0
dp[][][]=c;//电梯来电梯走,需要等电梯
dp[][][]=c;//电梯来楼梯走,需要等电梯
dp[][][]=;//楼梯来电梯走
dp[][][]=;//楼梯来楼梯走
for(int i=; i<=n; i++)
{
dp[i][][]=min(dp[i-][][]+b[i-],dp[i-][][]+b[i-]+c);
dp[i][][]=min(dp[i-][][]+b[i-],dp[i-][][]+b[i-]+c);
dp[i][][]=min(dp[i-][][]+a[i-],dp[i-][][]+a[i-]);
dp[i][][]=min(dp[i-][][]+a[i-],dp[i-][][]+a[i-]);
}
printf("0 ");
for(int i=;i<=n;i++)
{
if(i!=)
printf(" ");
int w=min(dp[i][][],dp[i][][]);
int ww=min(w,dp[i][][]);
int www=min(ww,dp[i][][]);
printf("%d",www);
}
printf("\n");
}
return ;
}
优化后的二维代码:
经过三维数组观察可得:
dp[i][][]=dp[i][][]=min(dp[i-][][]+b[i-],dp[i-][][]+b[i-]+c);
dp[i][][]=dp[i][][]=min(dp[i-][][]+a[i-],dp[i-][][]+a[i-]);
所以与从哪来有关,与到哪去无关
从而可以写成二维数组
代码如下:
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
const int N=2e5+; int a[N],b[N],dp[N][]; //dp[i][j][k] 到达第几层,j来,k走
//0电梯 1楼梯 int main()
{
int n,c;
while(~scanf("%d %d",&n,&c))
{
memset(dp,,sizeof(dp));
for(int i=; i<n; i++)
scanf("%d",&a[i]);//楼梯1
for(int i=; i<n; i++)
scanf("%d",&b[i]);//电梯0
dp[][]=c;
dp[][]=;
for(int i=; i<=n; i++)
{
dp[i][]=min(dp[i-][]+b[i-],dp[i-][]+b[i-]+c);
dp[i][]=min(dp[i-][]+a[i-],dp[i-][][]+a[i-]);
}
printf("0 ");
for(int i=;i<=n;i++)
{
if(i!=)
printf(" ");
int w=min(dp[i][],dp[i][]);
printf("%d",w);
}
printf("\n");
}
return ;
}
CodeForces1249E-By Elevator or Stairs?-好理解自己想不出来的dp的更多相关文章
- Codeforces1249E By Elevator or Stairs?
题意 给定整数c和数组a,b,\(a_i\)表示通过爬楼梯的方法从第\(i\)层到\(i+1\)层需要的时间,\(b_i\)表示通过坐电梯的方法从第\(i\)层到\(i+1\)层需要的时间,坐电梯前需 ...
- [题解]Mail.Ru Cup 2018 Round 1 - A. Elevator or Stairs?
[题目] A. Elevator or Stairs? [描述] Masha要从第x层楼去第y层楼找Egor,可以选择爬楼梯或者坐直升电梯.已知爬楼梯每层需要时间t1:坐直升电梯每层需要时间t2,直升 ...
- Codeforces 1249 E. By Elevator or Stairs?
传送门 首先显然下楼的操作一定是不优的,所以只要考虑上楼 设 $f[i]$ 表示到第 $i$ 层时需要的最少时间 那么首先考虑走楼梯,有转移,$f[i]=f[i-1]+a[i-1]$ 然后考虑坐电梯有 ...
- Codeforces 1249E By Elevator or Stairs? 题解
这题其实和 NIKKEI 2019-2-D Shortest Path on a Line 差不多的啦,都是一种最短路的变形,把多个点和边关联了起来. 题面 你要从一楼到 \(n\) 楼去,每层楼可以 ...
- javascript中继承(二)-----借用构造函数继承的个人理解
本人目录如下: 零.寒暄&回顾 一,借用构造函数 二.事件代理 三,call和apply的用法 四.总结 零.寒暄&回顾 上次博客跟大家分享了自己对原型链继承的理解,想看的同学欢迎猛击 ...
- 一步一步深入理解Dijkstra算法
先简单介绍一下最短路径: 最短路径是啥?就是一个带边值的图中从某一个顶点到另外一个顶点的最短路径. 官方定义:对于内网图而言,最短路径是指两顶点之间经过的边上权值之和最小的路径. 并且我们称路径上的第 ...
- Java的内部类真的那么难以理解?
01 前言 昨天晚上,我把车停好以后就回家了.回家后才发现手机落在车里面了,但外面太冷,冷到骨头都能感受到寒意——实在是不想返回一趟去取了(小区的安保还不错,不用担心被砸车玻璃),于是打定主意过几个小 ...
- 转发对python装饰器的理解
[Python] 对 Python 装饰器的理解的一些心得分享出来给大家参考 原文 http://blog.csdn.net/sxw3718401/article/details/3951958 ...
- http://python.jobbole.com/85056/ 简单 12 步理解 Python 装饰器,https://www.cnblogs.com/deeper/p/7482958.html另一篇文章
好吧,我标题党了.作为 Python 教师,我发现理解装饰器是学生们从接触后就一直纠结的问题.那是因为装饰器确实难以理解!想弄明白装饰器,需要理解一些函数式编程概念,并且要对Python中函数定义和函 ...
随机推荐
- Jplayer用法
引用js:jquery.jplayer.min.js; body里面必须有这个: <div id="jplayer"></div> jplayer停止方法 ...
- spring mvc 初始
今天带领大家开始第一天的spring mvc学习 首先我们要下载maven然后配置IDE 然后选择new 新建项目 然后选择maven,然后选择maven的webapp 然后创建springmvc ...
- Mosaic
Mosaic 是最古老的WEB浏览器,这是个套件FOR WINDOWS(包括TCP/IP,拨号,EMAIL等).
- 代码质量管理-Sonar
1.Sonar 摘要 Sonar 是一个用于代码质量管理的开放平台.通过插件机制,Sonar 可以集成不同的测试工具,代码分析工具,以及持续集成工具. 与持续集成工具(例如 Hudson/Jenkin ...
- NMS python实现
import numpy as np ''' 目标检测中常用到NMS,在faster R-CNN中,每一个bounding box都有一个打分,NMS实现逻辑是: 1,按打分最高到最低将BBox排序 ...
- Java DOM解析器 - 查询XML文档
这是需要我们查询的输入XML文件: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?xml version="1.0"?> ...
- Apache 2.4.12 64位+Tomcat-8.0.32-windows-x64负载集群方案
上次搞了Apache 2.2的集群方案,但是现在自己的机器和客户的服务器一般都是64位的,而且tomcat已经到8了.重新做Apache 2.4.12 64位+Tomcat-8.0.32-window ...
- 实用maven笔记四-打包&其他
通过使用maven的生命周期和丰富多样的插件,可以方便的将项目代码编译打包为自己需要的构件. maven默认项目主代码位置src/main/java目录,测试代码位置src/test/java目录.主 ...
- Spring Data JPA查询关联数据
1. Query方式@Query("select s from Store s join fetch s.products where s.user.id = :user_id") ...
- 【牛客网-剑指offer】跳台阶
题目: 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果). 考点: 递归和循环 思路: 1)利用二叉树,左孩子为跳一级,右孩子为跳两 ...