题目内容
问题描述
小 A 在想怎么从锁妖塔外面爬上去。锁妖塔的建造很特别,塔总共有 n n n 层,但是高度却不相同,这造成了小 A 爬过每层的时间也不同。小 A 会用仙术,每用一次可以让他向上跳一层或两层,但是每次跳跃后小 A 都将用完灵力,必须爬过至少一层才能再次跳跃(你可以认为小 A 需要跳两次一层才休息),小 A 想用最短的时间爬到塔顶,可是他不能找到时间最短的方案,所以请你帮他找到一个时间最短的方案让他爬到塔顶,小 A 只关心时间,所以你只要告诉他最短时间是多少就可以了。你可以最后跳到塔外即超过塔高。
输入格式
第一行一个数 n ( n ≤ 10000 ) n (n \le 10000) n(n≤10000),表示塔的层数。
接下来的 n n n 行每行一个数 ( ≤ 100 ) (\le 100) (≤100),表示从下往上每层的高度。
输出格式
一个数,表示最短时间。
样例输入
5
3
5
1
8
4
样例输出
1
提示
对
20
%
20 \%
20% 的数据,
n
≤
10
n \le 10
n≤10
对
40
%
40 \%
40% 的数据,
n
≤
100
n \le 100
n≤100
对
60
%
60 \%
60% 的数据,
n
≤
5000
n \le 5000
n≤5000
对
100
%
100 \%
100%的数据,
n
≤
10000
n \le10000
n≤10000
思路
这是一道很简单的动态规划题。
我们先用Time
记录爬第 i 层的用时,设dp[i]
表示爬到第 i 层需要的最小时间。
阶段:
- 从下面一层爬上来;
- 从下面二层爬上来,再从下面一层跳上来;
- 从下面三层爬上来,再从下面二层跳上来;
因此状态转移方程为: d p [ i ] = m i n ( d p [ i − 1 ] + T i m e [ i ] , d p [ i − 2 ] + T i m e [ i − 1 ] , d p [ i − 3 ] + T i m e [ i − 2 ] ) dp[i] = min(dp[i-1]+Time[i],dp[i-2]+Time[i-1],dp[i-3]+Time[i-2]) dp[i]=min(dp[i−1]+Time[i],dp[i−2]+Time[i−1],dp[i−3]+Time[i−2])
边界处理:
前 3 层要特殊处理,第一二三层都可以直接到达,所以用时为 0。参考代码中选择直接从 3 开始存储,避免错误。
因为可以跳到塔外,所以 i i i 最大情况是从 n n n 层往上跳 2 层,即 n + 2 n+2 n+2。
参考代码
#include<bits/stdc++.h>
using namespace std;
int n;
int Time[100005],dp[100005];
int main(){
scanf("%d",&n);
for(int i = 3; i <= n+2; i++){
scanf("%d",&Time[i]);
}
for(int i = 3; i <= n+2; i++){
dp[i] = min(dp[i-1]+Time[i],min(dp[i-2]+Time[i-1],dp[i-3]+Time[i-2]));
}
printf("%d",dp[n+2]);
return 0;
}