TopCoder——HillHiker(爬山问题)

本文介绍了如何解决HillHiker问题,基本思路是通过递归公式f(distance, height)=f(distance-1,height)+f(distance-1, height+1)+f(distance-1, height-1)。同时,针对maxHeight和landmarks的限制,需要在递归中进行条件判断。为了提升计算效率,建议使用查表法来优化算法。" 105971936,1358276,理解Git中的Dump分支快照,"['Git工具', '版本控制', '代码管理']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem Statement
    
A hiker has set out to conquer a hill. The trail guide for the hill lists information known about the hill. First, it lists how tall the hill is, and how far it is to the other side of the hill. Next, it gives a list of landmarks that will be encountered while hiking the hill. The only things that are known about these landmarks are their height, and the order in which they appear along the trail. Finally, on this hill, there are three types of terrain:

Type 1: rising terrain. In this type of terrain, the elevation of the hill rises one meter vertically for every meter that is traveled horizontally.
Type 2: level terrain. In this type of terrain, the elevation of the hill remains constant.
Type 3: falling terrain. This terrain's elevation falls one meter vertically for every meter that is traveled horizontally.
All three types of terrain can last for only multiples of one horizontal meter.
You will be given an int maxHeight (the maximum height of the hill, assuming the hill starts and ends at height 0), an int distance (how far horizontally one must travel to hike over the top and reach the bottom on the other side), and a int[] landmarks, which contains the heights of all the landmarks present on the trail. The order of the elements in landmarks is the order in which they will be encountered on the trail. All landmarks must be at least one horizontal meter apart.
Given all of this information, you must return how many different valid paths that the hiker could be facing. A path on the hill is a sequence consisting only of the three types of terrain for the entire distance of the hill. Two paths are different if and only if for at least one horizontal meter, the terrain type of one path is not the same as the terrain type of another path. A path is valid if and only if the path: 1. Starts at height 0 and ends at height 0 2. Has no other locations with height 0, or height below 0 (otherwise it would be two hills, or a valley) 3. Has at least one point where the height is equal to maxHeight (otherwise, the hill would be smaller) 4. Does not go above maxHeight (otherwise, it would be taller) 5. Is laid out such that the landmarks could be placed in the order given at points on the trail. Note that two landmarks cannot appear at the same point on the trail, even if they are at the same height. they must be at least 1 meter apart 
If no valid paths exist, return 0.
Definition
    
Class:
HillHike
Method:
numPaths
Parameters:
int, int, int[]
Returns:
long
Method signature:
long numPaths(int distance, int maxHeight, int[] landmarks)
(be sure your method is public)
Limits
    
Time limit (s):
2.000
Memory limit (MB):
64
Notes
The C++ 64 bit data type is long long
Constraints
distance will be between 2 and 100, inclusive.
maxHeight will be between 1 and 50, inclusive.
landmarks will contain between 0 and 50 elements, inclusive.
Each element of landmarks will be between 1 and maxHeight, inclusive.
The return value will be less than or equal to 2^63 - 1 (it will fit into a long)
Examples
0) 
5
2
{}

Returns: 3



1)    
2
45
{}
Returns: 0
2)   
5
2
{2,2}
Returns: 1
The only path which could contain both landmarks is:
            _
           / \
          /   \
Distance: 12345
3)  
8
3
{2,2,3,1}
Returns: 7
4)  
38
11
{4,5,8,5,6}

Returns: 201667830444



解题的基本思路就是上递归f(distance, height)=f(distance-1,height)+f(distance-1,height+1)+f(distance-1,height-1);

至于对于maxHeight和landmarks的限制,需要在递归过程中进行匹配,具体的看代码吧。

另外,为了提高效率,整个查表法,否则效率太低,达不到要求。

public class HillHike {

	int maxHeight=0;
	int landmarks[]=null;
	long table[][][]=null;
	long mutiTable[][][][]=null;
	public long numPaths(int distance, int maxHeight, int[] landmarks)
	{
		this.maxHeight=maxHeight;
		this.landmarks=landmarks;
		table=new long[distance][maxHeight+1][2];
		mutiTable=new long[distance][maxHeight+1][2][landmarks.length];
		for(int i=0;i<distance;i++)
		{
			for(int j=0;j<maxHeight+1;j++)
			{
				for(int k=0;k<2;k++)
				{
					table[i][j][k]=-1;
					for(int l=0;l<landmarks.length;l++)
						mutiTable[i][j][k][l]=-1;
				}
				
			}
		}
		return f(distance-1,1,landmarks.length-1,0);
	}
	
	
	public long f(int length,int height,int index,int flag)
	{
		//System.out.println(length+"\t"+height+"\t"+index+"\t"+flag);
		//匹配landmarks
		if(index>=0&&landmarks[index]==height)
			index--;
		//匹配是否有maxHeight
		if(height==maxHeight)
			flag=1;
		if(height>maxHeight||height<=0)
			return 0;
		if(length==1)
		{
			if(index<0&&flag==1&&height==1)
				return 1;
			else
				return 0;
		}
		//查表
		if(index<0&&table[length][height][flag]!=-1)
			return table[length][height][flag];
		if(index>=0&&mutiTable[length][height][flag][index]!=-1)
		{
			return mutiTable[length][height][flag][index];
		}
		
		long v=f(length-1,height+1,index,flag)+f(length-1,height,index,flag)+f(length-1,height-1,index,flag);
		//保存算过的数据
		if(index<0)
			table[length][height][flag]=v;
		else
			mutiTable[length][height][flag][index]=v;
		return v;
	}
	
	/*public static void main(String args[])
	{
		HillHike h=new HillHike();
		int landmarks[]={4,5,8,5,6};
		System.out.println(h.numPaths(38,11, landmarks));
	}*/
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值