算法题(六十四):搜狐2017笔试题——袋鼠过河——动态规划问题

题目描述

一只袋鼠要从河这边跳到河对岸,河很宽,但是河中间打了很多桩子,每隔一米就有一个,每个桩子上都有一个弹簧,袋鼠跳到弹簧上就可以跳的更远。每个弹簧力量不同,用一个数字代表它的力量,如果弹簧力量为5,就代表袋鼠下一跳最多能够跳5米,如果为0,就会陷进去无法继续跳跃。河流一共N米宽,袋鼠初始位置就在第一个弹簧上面,要跳到最后一个弹簧之后就算过河了,给定每个弹簧的力量,求袋鼠最少需要多少跳能够到达对岸。如果无法到达输出-1

输入描述:

输入分两行,第一行是数组长度N (1 ≤ N ≤ 10000),第二行是每一项的值,用空格分隔。

输出描述:

输出最少的跳数,无法到达输出-1

示例1

输入

5
2 0 1 1 1

输出

4

分析

这道题是典型的动态规划问题,用一个表格来分析。分析顺序为到第1个桩子时,最少需要多少步,到第2个桩子时,最少需要多少步,...到第n个桩子时,至少需要多少步。第n个桩子的最少步数与前面几个相关,同样第n-1个桩子的最少步数与前面步数也相关,....到第2个桩子的步数与第1个桩子的最少步数相关,而第1个桩子的步数一定为1。

步骤 柱子/相应可跳长度
2 0 1 1 1
a b c d e
第一步 1        
第二步 1 2      
第三步 1 2 2    
第四步 1 2 2 3  
第五步 1 2 3 3 4

如表所示,柱子用abcde来表示,相应可跳长度分别为2、0、1、1、1。

跳a桩时,总的最少用1步。

跳b桩时,只能从a跳到b,用1步,总的最少用2步(开始-a-b)。

跳c桩时,可以从a跳,可以从b跳。从a跳时,跳的长度可以达到c,故用1步;从b跳时,发现跳的长度为0,跳不到;故总的最少用2步(开始-a-c)。

跳d桩时,可以从a跳,从b跳,从c跳。从a和b跳发现跳不到d;所以只能从c跳到d,故总的最少用3(开始-a-c-d)。

跳e桩时,可以从a、b、c、d跳。从a、b、c跳发现跳不到e;所以只能从d跳到e,故总的最少用4(开始-a-c-d-e)。

动态规划问题的两个基本元素凑齐了,一个是递归基a_1=1,一个是递归过程a_n=min(a_{n-1}+x_{n-1},a_{n-2}+x_{n-2},...),其中a_n是到第n个桩子时最少步数,x_{n-1}为达到从第n-1个桩子到第n个桩子时需要的步数。

代码

package com.june.java;

public class DaiShu {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int n=5;
		int[] dp = new int[n+1];
		int[] nums = {2,0,1,1,1};
		dp[0]=1;
		for(int i=1; i<n+1; i++){
			dp[i] = 10000;
		}
		for(int i=1; i<=n; i++){
			for(int j=i-1; j>=0; j--){
				if(nums[j] == 0){
					continue;
				}
				if(j+nums[j]>=i){
					dp[i] = dp[i]<(dp[j]+1)?dp[i]:(dp[j]+1);
				}
			}
		}
		if(dp[n] == 10000){
			System.out.println("-1");
		}else{
			System.out.println(dp[n]-1);
		}
	}

}

猜你喜欢

转载自blog.csdn.net/qq_24034545/article/details/93641219
今日推荐