攀登宝塔
原题链接
攀登宝塔
描述
有一天,贝贝做了一个奇怪的梦,梦中他来到一处宝塔,他想要从塔的外面爬上去。这座宝塔的建造很特别,塔总共有n层,但是每层的高度却不相同,这造成了贝贝爬过每层的时间也不同。贝贝会用仙术,每用一次可以让他向上跳一层或两层,这时不会耗费时间,但是每次跳跃后贝贝都将用完灵力,必须爬过至少一层才能再次跳跃。贝贝想用最短的时间爬到塔顶,可是他找不到时间最短的方案,所以请你帮他找到一个时间最短的方案让他爬到塔顶,贝贝只关心时间,所以你只要告诉他最短时间是多少就可以了。你可以最后到达塔外即超过塔高。
输入
第一行一个数,表示塔的层数;
接下来的n行每行一个数不超过的正整数,表示从下往上每层的所需的时间。
输出
一个数,表示最短时间。
输入样例 1
5 3 5 1 8 4
输出样例 1
1
解决
这题使用dp来做。
状态转移方程
首先把原来的问题分为子问题。
我们可以把前i楼最快的设为吗?
显然不太行,题目中说不能连续地使用仙术。如果这么干,必然会产生后效性。
因为我们显然不知道在第层的时候,有没有用仙术。
怎么样避免后效性的出现。
---->设定两个数组,分别为第i层走的方法()和用仙术的方法()。
f[0][i]=min(f[0][i-1],f[1][i-1])+a[i];
f[1][i]=min(f[0][i-1],f[0][i-2]);
最后输出两种方法到达塔顶的最小值即可。
初始化
虽然解决了状态转移方程,但是初始化问题也需要解决。
我们本来其实是从在第0层开始爬的,但是我们是从第二层开始的(防止越界)。所以就要设为。飞上来的同理。
代码:
#include<bits/stdc++.h>
using namespace std;
int t,dp[2][11111],n,ans=99999999,a[11111];
int main(){
cin>>n;
for(int i=1;i<=n;i++) {
cin>>a[i];
}
for(int i=1;i<=n;i++) {
dp[0][i]=dp[1][i]=20000000;
}
dp[0][1]=a[1];dp[1][1]=0;
for(int i=2;i<=n;i++) {
dp[0][i]=min(dp[0][i-1]+a[i],dp[1][i-1]+a[i]);
dp[1][i]=min(dp[0][i-1],dp[0][i-2]);
}
cout<<min(dp[0][n],dp[1][n]);
return 0;
}

浙公网安备 33010602011771号