青蛙过桥

题目出处

青蛙过桥

一座长度为n的桥,起点的一端坐标为0,且在整数坐标i处有a[i]个石头【0<=a[i]<=4】,一只青蛙从坐标0处开始起跳,一步可以跳的距离为1或2或3【即每一步都会落在整数点处】,青蛙落在i处会踩着该点的所有石头,求青蛙跳出这座桥最少踩多少个石头。并且输出依次跳过的坐标点路线,如果存在多种路线,输出字典序最小的那一条。

输入格式:

第一行整数n(<15000),接着下一行会有n+1个由空格隔开的整数,即桥上各个坐标处石头数量。

输出格式:

第一行为踩着最少石头个数,第二行为依次跳过的坐标点【字典数最小的】。

输入样例:

这里给出两组输入。例如:

10
1 2 1 3 0 3 1 2 1 1 2
100
1 2 0 4 0 1 3 4 2 2 1 3 1 4 0 3 0 1 2 3 3 2 2 0 1 0 0 0 0 1 2 1 3 4 0 3 4 4 1 0 4 1 3 1 1 2 3 4 4 4 0 2 0 1 1 1 3 1 3 2 1 2 4 1 2 1 4 1 0 0 1 2 3 0 2 4 4 0 0 4 2 0 2 1 3 3 0 0 2 0 0 1 2 4 2 2 2 4 0

输出样例:

在这里给出对应的输出。例如:

4
0 2 4 6 8
36
0 2 4 5 8 10 12 14 16 17 20 23 25 26 27 28 31 34 35 38 39 41 44 47 50 52 54 57 60 63 65 68 69 70 72 74 77 78 81 82 85 88 89 91 92 94 97 100
 1 package frog;
 2 import java.util.Scanner;
 3 //import java.lang.Math;
 4 import java.util.Stack;
 5 /**
 6  * 
 7  * @author 刘金明  qliujinming@qq.com
 8  * @see http://www.cnblogs.com/liujinming/
 9  * 
10  */
11 public class Main {
12     private static int[] point;
13     private static int[] length;
14     private static int[] jump;
15     private static int start;
16 public static void main(String[] args){
17     Scanner sc=new Scanner(System.in);
18     int n=sc.nextInt();
19     start=sc.nextInt();
20     point=new int[n];length=new int[n];jump=new int[n];for(int i=0;i<length.length;i++) length[i]=-1;
21     for(int i=0;i<n;i++)point[i]=sc.nextInt();
22     recursion(n-1);
23     sc.close();
24     Stack<Integer> s=new Stack<Integer>();
25     //for(int i:length)System.out.print(i+" ");
26     for(int i=n-1;i>0;){
27         s.add(jump[i]+1);i=jump[i];
28     }
29     System.out.println(length[n-1]);
30     while(!s.isEmpty()){
31         System.out.print(s.pop()+" ");
32     }
33 }
34 /**
35  * 递归求解
36  */
37 
38 private static int recursion(int a){
39     if(length[a]>=0);
40     else if(a<=2){
41         length[a]=start;
42         jump[a]=-1;
43     }
44     else if(point[a-3]<=point[a-1]&&point[a-3]<=point[a-2]){
45         jump[a]=a-3;
46         length[a]=recursion(a-3)+point[a-3];
47     }
48     else if(point[a-2]<=point[a-1]){
49         int x=recursion(a-3)+point[a-3];int y=recursion(a-2)+point[a-2];
50         if(x<y){
51             length[a]=x;jump[a]=a-3;
52         }
53         else
54         length[a]=y;jump[a]=a-2;
55     }
56     else{
57         int x=recursion(a-3)+point[a-3];int y=recursion(a-2)+point[a-2];int z=recursion(a-1)+point[a-1];
58         if(x<y&&x<z){
59             length[a]=x;jump[a]=a-3;
60         }
61         else if(y<z){
62             length[a]=y;jump[a]=a-2;
63         }
64         else
65             length[a]=z;jump[a]=a-1;
66     }
67         
68         //length[a]=Math.min(recursion(a-3)+point[a-3],Math.min(recursion(a-2)+point[a-2], recursion(a-1)+point[a-1]));
69     return length[a];
70 }
71 }
实现代码

 样例是我照着图输入进去的,貌似输漏了几个数,请以文首的链接处的图片为准

另外这并不是什么严谨的题目(看得到第一组输出里面最后一个数字不是终点10,而是终点的前一个位置,而第二组输出里面最后一个数字是终点100),我所求的也并不是字典数最小的答案,不过思路在这里了

原文地址:https://www.cnblogs.com/liujinming/p/7612648.html