攀登宝塔

原题链接

攀登宝塔

描述

有一天,贝贝做了一个奇怪的梦,梦中他来到一处宝塔,他想要从塔的外面爬上去。这座宝塔的建造很特别,塔总共有n层,但是每层的高度却不相同,这造成了贝贝爬过每层的时间也不同。贝贝会用仙术,每用一次可以让他向上跳一层或两层,这时不会耗费时间,但是每次跳跃后贝贝都将用完灵力,必须爬过至少一层才能再次跳跃。贝贝想用最短的时间爬到塔顶,可是他找不到时间最短的方案,所以请你帮他找到一个时间最短的方案让他爬到塔顶,贝贝只关心时间,所以你只要告诉他最短时间是多少就可以了。你可以最后到达塔外即超过塔高。

输入

第一行一个数n(n10000)n(n≤10000),表示塔的层数;

接下来的n行每行一个数不超过100100的正整数,表示从下往上每层的所需的时间。

输出

一个数,表示最短时间。

输入样例 1

5 3 5 1 8 4

输出样例 1

1


解决

这题使用dp来做。

状态转移方程

首先把原来的问题分为子问题。

我们可以把前i楼最快的设为f[i]f[i]吗?

显然不太行,题目中说不能连续地使用仙术。如果这么干,必然会产生后效性。

因为我们显然不知道在第ii层的时候,有没有用仙术。

怎么样避免后效性的出现。

---->设定两个数组,分别为第i层走的方法(f[0][i]f[0][i])和用仙术的方法(f[1][i]f[1][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层开始爬的,但是我们是从第二层开始的(防止越界)。所以f[0][1]f[0][1]就要设为a[1]a[1]。飞上来的同理。

代码:

#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;
}
posted @ 2022-03-15 14:04  cjrqwq  阅读(33)  评论(0)    收藏  举报  来源