CodeForces-1249E By Elevator or Stairs? (动态规划求最短时间)

题目描述

您打算在一栋 n n n 层的大楼里购买一套公寓。从底层到顶层,楼层编号从 1 1 1 n n n。您想知道从第一层(底层)到达每一层所需的最短总时间。

规定:

  • a i ( 1 ≤ i ≤ n − 1 ) a_i(1 \leq i \leq n-1) ai(1in1) ,是使用楼梯从第 i i i 层到第 i + 1 i+1 i+1 层所需的时间。
  • b i ( 1 ≤ i ≤ n − 1 ) b_i(1 \leq i \leq n-1) bi(1in1) ,是使用电梯从第 i i i 层到第 i + 1 i+1 i+1 层所需的时间。还有一个值 c c c,是使用电梯的时间开销(您需要等待,电梯门太慢了)。

在一次移动中,您可以通过两种不同的方式从您所在的楼层 x x x 到任意楼层 y y y ( x ≠ y ) (x≠y) x=y

  • 如果使用楼梯,只需将相应的 a i a_i ai 值相加即可。从形式上看,需要 ∑ i = m i n ( x , y ) m a x ( x , y ) − 1 a i \sum\limits_{i=min(x,y)}^{max(x,y)-1}a_i i=min(x,y)max(x,y)1ai个时间单位。
  • 如果使用电梯,只需将 c c c 和相应的 b i b_i bi 值相加即可。从形式上看,需要 c + ∑ i = m i n ( x , y ) m a x ( x , y ) − 1 b i c+ \sum\limits_{i=min(x,y)}^{max(x,y)-1}b_i c+i=min(x,y)max(x,y)1bi个时间单位。

您可以执行任意数量的移动(可能是零)。

所以你的任务是为每个 i i i 确定从第 1 1 1 层(底层)到达第 i i i 层所需的最短总时间。

输入格式

输入的第一行包含两个整数 n n n c c c ( 2 ≤ n ≤ 2 ⋅ 1 0 5 , 1 ≤ c ≤ 1000 ) (2≤n≤2⋅10^5,1≤c≤1000) 2n2105,1c1000,分别表示大楼的层数和乘坐电梯的时间。

输入的第二行包含 n − 1 n-1 n1 个整数 a 1 , a 2 , . . . , a n − 1 ( 1 ≤ a i ≤ 1000 ) a_1,a_2,...,a_{n-1}(1≤a_i≤1000) a1,a2,...,an11ai1000,其中 a i a_i ai 是使用楼梯从第 i i i 层到第 i + 1 i+1 i+1 层所需的时间。

输入的第三行包含 n − 1 n-1 n1 个整数 b 1 、 b 2 . . . . . . 、 b n − 1 ( 1 ≤ b i ≤ 1000 ) b_1、b_2......、b_{n-1}(1≤b_i≤1000) b1b2......bn11bi1000,其中 b i b_i bi 是乘坐电梯从第 i i i 层到第 i + 1 i+1 i+1 层所需的时间。

输出格式

打印 n n n 个整数 t 1 、 t 2 . . . . . . 、 t n t_1、t_2......、t_n t1t2......tn,其中 t i t_i ti 是在可以任意移动的情况下,从第一层到达第 i i i 层所需的最短总时间。

样例输入1

10 2
7 6 18 6 16 18 1 17 17
6 9 3 10 9 1 10 1 5

样例输出1

0 7 13 18 24 35 36 37 40 45 

样例输入2

10 1
3 2 3 1 3 3 1 4 1
1 2 3 4 4 1 2 1 3

样例输出2

0 2 4 7 8 11 13 14 16 17 

提交链接

https://codeforces.com/problemset/problem/1249/E

解析

10 2
7 6 18 6 16 18 1 17 17
6 9 3 10 9 1 10 1 5

到第二层,走楼梯需要 7 7 7,做电梯需要 6 6 6,但是有启动时间 2 2 2,所以从第一层到第二层走楼梯。以此类推。。。。
若到某一层是走楼梯上来的,再到高一层若想坐电梯需要考虑启动时间。
若到某一层是做电梯上来的,再到高一层若继续做电梯,则不需要考虑启动时间。

总共有两种选择,做电梯或走楼梯。
d p [ i ] [ 0 ] dp[i][0] dp[i][0]:表示到第 i i i 层是走楼梯到达的。
d p [ i ] [ 1 ] dp[i][1] dp[i][1]:表示到第 i i i 层做电梯到达的。

参考代码

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=2e5+9,inf=0x3f3f3f3f;
int n,c;
int a[maxn],b[maxn];
int dp[maxn][2];                 //dp[i][0]:走楼梯到达第i层  dp[i][1]:坐电梯到达第i层
int main()
{
	cin>>n>>c;                //n层楼梯  坐电梯的时间为c

	memset(dp,inf,sizeof(dp));   //初始化
	dp[1][0]=0;
	dp[1][1]=c;

	for(int i=1; i<n; i++)
		cin>>a[i];              //a[i]:走楼梯(i-->i+1)的时间
	for(int i=1; i<n; i++)
		cin>>b[i];              //b[i]:坐电梯(i-->i+1)的时间
	for(int i=1; i<n; i++)
	{
		dp[i+1][0]=min(dp[i+1][0],dp[i][1]+a[i]);  //走楼梯
		dp[i+1][0]=min(dp[i+1][0],dp[i][0]+a[i]);

		dp[i+1][1]=min(dp[i+1][1],dp[i][1]+b[i]);  //坐电梯
		dp[i+1][1]=min(dp[i+1][1],dp[i][0]+b[i]+c);

	}
	for(int i=1; i<=n; i++)
			cout<<min(dp[i][0],dp[i][1])<<" ";
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zaiyang遇见

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值