You are given a non-negative integer k. There exists a staircase with an infinite number of stairs, with the lowest stair numbered 0.
Alice has an integer jump, with an initial value of 0. She starts on stair 1 and wants to reach stair k using any number of operations. If she is on stair i, in one operation she can:
Go down to stair i - 1. This operation cannot be used consecutively or on stair 0.
Go up to stair i + 2jump. And then, jump becomes jump + 1.
Return the total number of ways Alice can reach stair k.
Note that it is possible that Alice reaches the stair k, and performs some operations to reach the stair k again.
Input: k =0Output: 2Explanation:
The 2 possible ways of reaching stair 0 are:* Alice starts at stair 1.* Using an operation of the first type, she goes down 1 stair to reach stair 0.* Alice starts at stair 1.* Using an operation of the first type, she goes down 1 stair to reach stair 0.* Using an operation of the second type, she goes up 20 stairs to reach stair 1.* Using an operation of the first type, she goes down 1 stair to reach stair 0.
Input: k =1Output: 4Explanation:
The 4 possible ways of reaching stair 1 are:* Alice starts at stair 1. Alice is at stair 1.* Alice starts at stair 1.* Using an operation of the first type, she goes down 1 stair to reach stair 0.* Using an operation of the second type, she goes up 20 stairs to reach stair 1.* Alice starts at stair 1.* Using an operation of the second type, she goes up 20 stairs to reach stair 2.* Using an operation of the first type, she goes down 1 stair to reach stair 1.* Alice starts at stair 1.* Using an operation of the first type, she goes down 1 stair to reach stair 0.* Using an operation of the second type, she goes up 20 stairs to reach stair 1.* Using an operation of the first type, she goes down 1 stair to reach stair 0.* Using an operation of the second type, she goes up 21 stairs to reach stair 2.* Using an operation of the first type, she goes down 1 stair to reach stair 1.
At each step, Alice can either go up (with a jump that increases each time) or go down (but not consecutively and not from stair 0). The state is defined by the current stair, current jump, and whether the last move was down. We use memoization to avoid recomputation.
classSolution {
publicintnumberOfWays(int k) {
Map<String, Integer> memo =new HashMap<>();
return dp(1, 0, false, k, memo);
}
privateintdp(int i, int jump, boolean lastDown, int k, Map<String, Integer> memo) {
if (i == k) return 1;
String key = i +","+ jump +","+ lastDown;
if (memo.containsKey(key)) return memo.get(key);
int res = 0;
if (!lastDown && i > 0) res += dp(i-1, jump, true, k, memo);
res += dp(i+2*jump, jump+1, false, k, memo);
memo.put(key, res);
return res;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
classSolution {
funnumberOfWays(k: Int): Int {
val memo = mutableMapOf<Triple<Int,Int,Boolean>, Int>()
fundp(i: Int, jump: Int, lastDown: Boolean): Int {
if (i == k) return1val key = Triple(i, jump, lastDown)
if (key in memo) return memo[key]!!var res = 0if (!lastDown && i > 0) res += dp(i-1, jump, true)
res += dp(i+2*jump, jump+1, false)
memo[key] = res
return res
}
return dp(1, 0, false)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
classSolution:
defnumberOfWays(self, k: int) -> int:
from functools import lru_cache
@lru_cache(None)
defdp(i: int, jump: int, last_down: bool) -> int:
if i == k:
return1 res =0ifnot last_down and i >0:
res += dp(i-1, jump, True)
res += dp(i+2*jump, jump+1, False)
return res
return dp(1, 0, False)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
impl Solution {
pubfnnumber_of_ways(k: i32) -> i32 {
use std::collections::HashMap;
fndp(i: i32, jump: i32, last_down: bool, k: i32, memo: &mut HashMap<(i32,i32,bool), i32>) -> i32 {
if i == k { return1; }
iflet Some(&v) = memo.get(&(i, jump, last_down)) { return v; }
letmut res =0;
if!last_down && i >0 {
res += dp(i-1, jump, true, k, memo);
}
res += dp(i+2*jump, jump+1, false, k, memo);
memo.insert((i, jump, last_down), res);
res
}
letmut memo = HashMap::new();
dp(1, 0, false, k, &mut memo)
}
}