1. 程式人生 > >爬塔難題(dp)

爬塔難題(dp)

爬塔難題(dp)

Problem Description
小學妹被困在了雷鋒塔的頂端,英熊要去營救她。雷鋒塔的層數為n,每層的高度都不一樣。英熊每爬一層所耗費的時間與該層高度相同。
然鵝,英熊有一張飛毯,飛毯可以讓英熊直接飛過一層或兩層。飛毯速度很快,所以坐飛毯不需要時間。
每飛行一次,飛毯都會耗費所有能量,需要英熊自己至少爬上一層樓後才能恢復。請你幫英熊計算出他最短能達到塔頂救小學妹的時間,飛毯初始滿能量。
小學妹被困在了雷鋒塔的頂端,英熊要去營救她。雷鋒塔的層數為n,每層的高度都不一樣。英熊每爬一層所耗費的時間與該層高度相同。
然鵝,英熊有一張飛毯,飛毯可以讓英熊直接飛過一層或兩層。飛毯速度很快,所以坐飛毯不需要時間。
每飛行一次,飛毯都會耗費所有能量,需要英熊自己至少爬上一層樓後才能恢復。請你幫英熊計算出他最短能達到塔頂救小學妹的時間,飛毯初始滿能量。
Input
第一行有一個整數T(0<=t<=1000),表示樣例的個數。
接下來的T行,每行為一組樣例,每行由n+1個正整數(n<=100000,所有正整數<=100000)組成,第一個整數代表雷峰塔的層數,剩下的整數表示每層的高度。
Output
輸出達到塔頂救小學妹所需的最短時間
Sample Input
2
3 1 2 3
5 4 3 1 2 3
Sample Output
1
1
程式碼如下:

#include<iostream>
#include<cstring>
using namespace std;
/*
爬塔難題
我們要到達的是 
方案一(直接爬上去,不用飛毯):dp[i-1]+height[i],走的是height[i] 
方案二(飛毯只飛一層):dp[i-2]+height[i-1],走的是height[i-1],height[i]是飛的 
方案三(飛毯飛兩層): dp[i-3]+height[i-2],走的是 height[i-2],height[i-1]和height[i]是飛的 
*/
int n;  //塔的層數 
int dp[100010];  //狀態轉移陣列 
int height[100010];   //每層塔的高度 
int main()
{
	int t,temp;
	cin>>t;  //樣例數 
	while(t--)
	{
		cin>>n;   //塔的層數 
		for(int i=3;i<=n+2;i++)   //為了防止陣列溢位,i從3開始 
		   cin>>height[i];      //輸入塔的高度 
		memset(dp,0,sizeof(dp));   //初始化狀態轉移陣列 
		for(int i=3;i<=n+2;i++)   //求出三種方案的最小值 
		{
			if(dp[i-1]+height[i]<dp[i-2]+height[i-1])
			   temp=dp[i-1]+height[i];
			else temp=dp[i-2]+height[i-1];
			if(temp>dp[i-3]+height[i-2])
			   temp=dp[i-3]+height[i-2];
			dp[i]=temp;   //當前層數的狀態轉移陣列得到填入 
		}
		cout<<dp[n+2]<<endl;   //輸出結果 
	}
	return 0;
}