题目描述
牛牛很喜欢在数字序列中跳跃
现在他站在 1 号位置, 每次跳跃,他可以向后跳一步(即从 i 调到 i + 1),也可以跳到该位置后的任意一个与该位置上的数字相同的位置
请问他最少需要跳多少步才能到 N 号位置?
输入描述
第一行输入一个整数 N ,表示数字序列的长度
接下来一行为一个仅由数字 0 - 9 构成的数字串
输出描述
输出到达 N 号位置最少的步数
题目分析
动态规划思想:
1、dp[ i ] 表示 跳到第 i 号位置需要的最少步数
2、根据题意,跳到第 i 个位置,可以从 i - 1 号位置到达,以及从 第一次出现和该台阶上数字相同的位置到达 ,取二者最小值即为到达 i 号位置的最小步数
3、状态转移方程 :dp[ i ] = Math.min ( dp[ i - 1 ] , temp[ arr[ i ] ] ) + 1
注:arr[ i ] 表示第 i 号位置上的数字, 题目输入给定
temp 数组记录 数字 0 - 9 第一次出现时所需要的最小步数
import java.util.*;
public class Main {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] arr = new int[n];
sc.nextLine();
String str = sc.nextLine();
for (int i = 0; i < n; i++) {
arr[i] = str.charAt(i)-'0';
}
int[] dp = new int[n];
int[] temp = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
temp[arr[0]] = 0;
dp[0] = 0;
for(int i = 1; i < n;i ++) {
if(temp[arr[i]] != -1){
// 说明 arr[i] 的数字不是第一次出现
dp[i] = Math.min(temp[arr[i]] , dp[i - 1]) + 1;
} else {
// 第一次出现,只能从上一步跳达
temp[arr[i]] = dp[i] = dp[i - 1] + 1;
}
}
System.out.println(dp[n - 1]);
}
}