牛牛一开始在第0层,它每次可以跳奇数层台阶,他想跳到第n层,但是它不希望在跳跃的过程中踩到积水。
已知有
请问牛牛在不踩到积水的情况下跳到第n层有多少种不同的方案。如果不可能到达第
为了防止答案过大,答案对1e9+7取模。
9,3,[1,3,5]
2
因为1,3,5都不能走,所以第一步可以跳到第7层或者第9层所以一共两种方案:1. 第一步跳7,第二步跳1,第三步跳12. 第一步跳9
第一个参数代表台阶的阶数
第二个参数m代表有多少层台阶有积水
第三个参数vector a包含m个数字,每个数字代表第
层台阶有积水。保证
没有重复元素且以升序给出。
class Solution {
public:
/**
* 又见台阶
* @param n int整型
* @param m int整型
* @param a int整型vector
* @return int整型
*/
int solve(int n, int m, vector<int>& a) {
// write code here
const int MOD = 1e9 + 7;
vector<int> dp(n+1, 0);
dp[0] = 1;
//分别表示奇数台阶和偶数台阶的方法数的前缀和,在初始状态下因为有dp[0] = 1,所以evenSum = 1
int oddSum = 0, evenSum = 1;
int idx = 0; // 记录当前遍历到的a数组的下标
for(int i = 1; i <= n; ++i){
// 这个if语句用于跳过a数组中的台阶,即积水台阶
if(i == a[idx]){
idx++;
continue;
}
// 如果当前台阶是奇数,则只能由之前的偶数台阶跳上来
if(i & 1){
// 更新到达当前台阶的方法数
dp[i] = (dp[i] + evenSum) % MOD;
// 利用dp[i]更新奇数台阶的总方法数
oddSum = (oddSum + dp[i]) % MOD;
}
// 如果当前台阶是偶数,则只能由之前的奇数台阶跳上来
else{
dp[i] = (dp[i] + oddSum) % MOD;
evenSum = (evenSum + dp[i]) % MOD;
}
}
return dp[n];
}
};
int solve(int n, int m, vector<int>& a) {
// write code here
const int mod = 1000000007;
int odd_sum = 0; // 前面奇数层位置的方案数的和
int even_sum = 1; // 前面偶数层位置的方案数的和,位置0作为偶数
int water_index = 0; // 有水台阶的索引
for (int i = 1; i < n; i++) { // 最后一层先不跳
// 如果当前有水台阶层数小于 i, 那么一直向后走。是为了判断i层是否有水
while (water_index < a.size() && a[water_index] < i) { //
water_index++;
}
if (water_index >= a.size() || i != a[water_index]) { // i层没水
if (i % 2 == 1) { // i层是奇数。
odd_sum = (odd_sum + even_sum) % mod; // i层之前的奇数层方案数 + 第i层方案数。第i层方案数是从偶数层跳奇数个台阶而来。
} else {
even_sum = (even_sum + odd_sum) % mod; // i层之前的偶数层方案数 + 第i层方案数。第i层方案数是从奇数层跳奇数个台阶而来。
}
}
}
if (a.back() == n) {
return 0;
} else {
return ((n % 2 == 1) ? even_sum : odd_sum); // 最后一层是奇数,则从偶数层跳过来。是偶数,则从奇数层跳过来。
}
} class Solution {
public:
/**
* 又见台阶
* @param n int整型
* @param m int整型
* @param a int整型vector
* @return int整型
*/
int solve(int n, int m, vector<int>& a) {
// write code here
const int MOD = 1e9 + 7;
int first = 0; //奇数
int second = 1; //偶数
int water_idx = 0;
for(int i = 1; i <= n; i++) {
if(a[water_idx] == i) {
water_idx++;
continue;
}
if(i % 2 == 0) {
//偶数
second = second + first;
second %= MOD;
}
else {
//奇数
first = first + second;
first %= MOD;
}
}
if(a.back() == n) {
return 0;
}
return n % 2 == 0 ? first : second;
}
}; import java.util.*;
public class Solution {
/**
* 又见台阶
* @param n int整型
* @param m int整型
* @param a int整型一维数组
* @return int整型
*/
int MAX=1000000007;
public int solve (int n, int m, int[] a) {
// write code here;
int[] dp=new int[n+1];
for(int i:a){
dp[i]=-1;
}
int[] pre= new int[n+1];//前缀和
for(int i=0;i<=n;i++){
if(dp[i]<0){
dp[i]=0;
}else{
if(i%2==0){
//如果是偶数,
dp[i]=i>=1?pre[i-1]:0;
dp[i]=dp[i]%MAX;
}else{
dp[i]=i>=1?pre[i-1]:0;
dp[i]=dp[i]%MAX;
dp[i]=dp[i]+1;
}
}
pre[i]=(i>=2?pre[i-2]:0)+dp[i];
pre[i]=pre[i]%MAX;
//preJ
}
return dp[n];
}
}