前些时间虚渊玄的巨献小圆着实火了一把。 在黑长直(小炎)往上爬楼去对抗魔女之夜时,她遇到了一个问题想请你帮忙。 因为魔女之夜是悬浮在半空的,所以她必须要爬楼,而那座废墟一共有n层,而且每层高度不同,这造成小炎爬每层的时间也不同。不过当然,小炎会时间魔法,可以瞬间飞过一层或者两层[即不耗时]。但每次瞬移的时候她都必须要至少往上再爬一层(在这个当儿补充魔力)才能再次使用瞬移。爬每单位高度需要消耗小炎1秒时间。 消灭魔女之夜是刻不容缓的,所以小炎想找你帮她找出一种最短时间方案能通往楼顶。
本题有多组数据,以文件输入结尾结束。
每组数据第一行一个数字N(1 <= N <= 10000),代表楼层数量。
接下去N行,每行一个数字H(1 <= H <= 100),代表本层的高度。对于每组数据,输出一行,一个数字S,代表通往楼顶所需的最短时间。
设dp[i][0/1]表示走到第i层有没有使用魔法的最小步数。
我们设层数从1开始,那么第i个楼梯是连接 i~i+1 层的,所以答案是min(dp[n+1][1],dp[n+1][0])
上代码
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; template<class T> inline void read(T &_a){ bool f=0;int _ch=getchar();_a=0; while(_ch<'0' || _ch>'9'){if(_ch=='-')f=1;_ch=getchar();} while(_ch>='0' && _ch<='9'){_a=(_a<<1)+(_a<<3)+_ch-'0';_ch=getchar();} if(f)_a=-_a; } int n,h[10001],dp[10001][2]; int main() { while(scanf("%d",&n)==1) { memset(dp,0x7f,sizeof(dp)); dp[0][0]=0; dp[1][1]=0; dp[1][0]=0; for (register int i=1;i<=n;++i) read(h[i]); for (register int i=2;i<=n+1;++i) { dp[i][0]=min(dp[i-1][1],dp[i-1][0])+h[i-1]; dp[i][1]=min(dp[i-1][0],min(min(dp[i-2][1]+h[i-2],dp[i-2][0]),dp[i-3][1]+h[i-2])); } printf("%d ",min(dp[n+1][0],dp[n+1][1])); } return 0; }