一、问题描述
小蓝来到了一座高耸的楼梯前,楼梯共有 N 级台阶,从第 0 级台阶出发。小蓝每次可以迈上 1 级或 2 级台阶。但是,楼梯上的第 a1 级、第 a2 级、第 a3 级,以此类推,共 M 级台阶的台阶面已经坏了,不能踩上去。
现在,小蓝想要到达楼梯的顶端,也就是第 N 级台阶,但他不能踩到坏了的台阶上。请问他有多少种不踩坏了的台阶到达顶端的方案数?
由于方案数很大,请输出其对 1e9+7 取模的结果。
输入格式
第一行包含两个正整数 N(1≤N≤1e5)和 M(0≤M≤N),表示楼梯的总级数和坏了的台阶数。
接下来一行,包含 M 个正整数 a1,a2,…,aM(1≤a1<a2<a3<aM≤N),表示坏掉的台阶的编号。
输出格式
输出一个整数,表示小蓝到达楼梯顶端的方案数,对 1e9+7取模。
样例输入
6 1
3
样例输出
4
二、代码展示
import java.util.Arrays;
import java.util.Scanner;
public class ikun {
static long mod = (long) 1e9 + 7;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
long[] dp = new long[n + 1];
boolean[] broken = new boolean[n + 1]; // 标记坏掉的台阶
// 初始化坏掉的台阶
for (int i = 0; i < m; i++) {
int k = scanner.nextInt();
broken[k] = true;
}
// 初始化 dp 数组
dp[0] = 1; // 从第 0 级台阶出发只有一种方式
for (int i = 1; i <= n; i++) {
if (broken[i]) {
dp[i] = 0; // 坏掉的台阶无法到达
continue;
}
if (i >= 1) {
dp[i] = (dp[i] + dp[i - 1]) % mod;
}
if (i >= 2) {
dp[i] = (dp[i] + dp[i - 2]) % mod;
}
}
System.out.println(dp[n]);
}
}
初始化:
dp[0] = 1
:从第 0 级台阶出发只有一种方式。
broken
数组用于标记哪些台阶是坏掉的。动态规划计算:
对于每个台阶
i
,如果它是坏掉的,则dp[i] = 0
。否则,
dp[i] = dp[i-1] + dp[i-2]
,并对结果取模1e9+7
。输出结果:
最终输出
dp[n]
,即到达第n
级台阶的方案数。