动态规划相关题目

匿名 (未验证) 提交于 2019-12-03 00:34:01

一 袋鼠过河

题目描述:

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

import java.util.Scanner; public class Main{     public static void main(String[] args){         Scanner sc=new Scanner(System.in);         int n=sc.nextInt();         int[] num=new int[n];         for(int i=0;i<n;i++)             num[i]=sc.nextInt();         int[] jump=new int[n+1];         for(int m=1;m<n+1;m++)             jump[m]=10000;         jump[0]=1;                   for(int k=1;k<=n;k++){             //每次 看走到第k个地方的时候,走了多少步             //走的步数与上一步的走法有关             for(int j=k-1;j>=0;j--){                if(num[j]==0)                    continue;                 if(j+num[j]>=k)//从j的位置到k的位置是可达的,即一步能跳到                     jump[k]=Math.min(jump[k],jump[j]+1);//则到位置k的步数取当前最小值             }         }         if(jump[n]==10000)             System.out.println(-1);         else             System.out.println(jump[n]-1);               } }

题目二:跳石板

题目描述:

小易来到了一条石板路前,每块石板上从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号石板

import java.util.Scanner; import java.util.ArrayList; public class Main{     public static void main(String[] args){         Scanner sc=new Scanner(System.in);         int n=sc.nextInt();         int m=sc.nextInt();         //维护一个整型数组,存放从初始位置到到每一个位置的所需要走的最少步骤         //注意这里数组下标从0到n-1里面存的都是没有用的         //除了下标为n的位置赋值为0 其余都赋值为最大值          int[] step=new int[m+1];         for(int k=n+1;k<m+1;k++){             step[k]=Integer.MAX_VALUE;         }                      //这样写会超时 换一种思路:不是每次遍历之前的每一个位置然后判断其是否满足条件            //而是直接看当前位置能到达的所有位置,即当前位置的所有约数+i             //相较于之前的思路 是一种从前到后的想法 之前是每一个位置 从后往前看          /*   for(int i=n+2;i<=m;i++){                          //到每一个位置上的最少步数都与之前的走法有关             for(int j=i-2;j>=n;j--){                 if(step[j]==Integer.MAX_VALUE)                       continue;                                 if(j%(i-j)==0 && i-j!=j){                     //可达且约数不是本身也不是1,则最少步数取当前最短和上一步最短+1中的最小值                     step[i]=Math.min(step[i],step[j]+1);                 }             }             }             */             //新思路实现:         for(int i=n;i<=m-2;i++){             //如果当前位置本身就不可达 则跳过             //注意:这个方法是在这里判断的 因为当前位置已经在遍历之前位置的时候更新过了 如果还是最大值 则说明不可达             //之前方法是从后往前更新的 所以不能上来就判断             if(step[i]==Integer.MAX_VALUE)                 continue;             ArrayList<Integer> factors=getFactors(i);//存放当前位置的所有约数             //遍历所有约数             for(int j=0;j<factors.size();j++){                 int temp=i+factors.get(j);                 if(temp<=m){                     step[temp]=Math.min(step[temp],step[i]+1);                 }             }         }         if(step[m]==Integer.MAX_VALUE){             System.out.println(-1);         }else{             System.out.println(step[m]);         }     }     //求除了本身和1之外的所有约数的函数     public static ArrayList<Integer> getFactors(int n){         ArrayList<Integer> res=new ArrayList<Integer>();         //int bound=Math.sqrt(n);         for(int i=2;i*i<=n;i++){             if(n%i==0){                 res.add(i);                 if(i!=n/i)                     res.add(n/i);              }                         }         return res;     } }

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!