跳石板

题目:

  小易来到了一条石板路前,每块石板上从1挨着编号为:1、2、3.......
  这条石板路要根据特殊的规则才能前进:对于小易当前所在的编号为K的 石板,小易单次只能往前跳K的一个约数(不含1和K)步,即跳到K+X(X为K的一个非1和本身的约数)的位置。 小易当前处在编号为N的石板,他想跳到编号恰好为M的石板去,小易想知道最少需要跳跃几次可以到达。
  例如:
  N = 4,M = 24:
  4->6->8->12->18->24
  于是小易最少需要跳跃5次,就可以从4号石板跳到24号石板

 

解题思路:

  (1)递归,每走一步都有可能产生很多可能,直到走到目的地,最后比较哪个方案的跳跃次数最少。会有很多重复计算。在某个中间点继续往下走,是在最小跳跃次数的基础上继续往下走。

  (2)动态规划,计算到达从n - m每一个石块最小的跳跃次数,从而得到最后m的最小跳跃次数。需要一个辅助数组来记录每一个石块所需跳跃的次数。

 

import java.util.Scanner;
import java.util.ArrayList;
public class Main{
    public static void main(String args[]){
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int m = in.nextInt();
        int temp[] = new int[m + 1];
        for (int i = n + 1; i <= m; i++){
            temp[i] = m ;
        }
        for (int i = n; i <= m; i++){
            if (temp[i] == m ){
                continue;
            }
            ArrayList<Integer> list = find(i);
            for (int step : list){
                int count = 1 + temp[i];
                if ((i + step) <= m && count < temp[i + step]){
                    temp[i + step] = count;
                }
            }
        }
        if (temp[m] == m){
            System.out.println(-1);
            return;
        }else{
            System.out.println(temp[m]);
        }
    }
   
    
    public static ArrayList<Integer> find(int n){
        ArrayList<Integer> list = new ArrayList<>();
        for (int i = 2; i <= Math.sqrt(n); i++){
            if (n % i == 0){
                list.add(i);
                if (n / i != i){
                    list.add(n/i);
                }
            }
            
        }
        return list;
    }
}

 

posted @ 2020-04-13 16:00  lucy_cui  阅读(116)  评论(0)    收藏  举报