the last one in Biweekly Contest 34.
Difficulty : Hard
Related Topics : Dynamic Programming
You are given an array of distinct positive integers locations where
locations[i]
represents the position of cityi
. You are also given integersstart
,finish
andfuel
representing the starting city, ending city, and the initial amount of fuel you have, respectively.At each step, if you are at city
i
, you can pick any cityj
such thatj != i
and0 <= j < locations.length
and move to cityj
. Moving from cityi
to cityj
reduces the amount of fuel you have by|locations[i] - locations[j]|
. Please notice that|x|
denotes the absolute value ofx
.Notice that
fuel
cannot become negative at any point in time, and that you are allowed to visit any city more than once (includingstart
andfinish
).Return the count of all possible routes from
start
tofinish
.Since the answer may be too large, return it modulo 10^9 + 7.
Input: locations = [2,3,6,8,4], start = 1, finish = 3, fuel = 5 Output: 4 Explanation: The following are all possible routes, each uses 5 units of fuel: 1 -> 3 1 -> 2 -> 3 1 -> 4 -> 3 1 -> 4 -> 2 -> 3
Input: locations = [4,3,1], start = 1, finish = 0, fuel = 6 Output: 5 Explanation: The following are all possible routes: 1 -> 0, used fuel = 1 1 -> 2 -> 0, used fuel = 5 1 -> 2 -> 1 -> 0, used fuel = 5 1 -> 0 -> 1 -> 0, used fuel = 3 1 -> 0 -> 1 -> 0 -> 1 -> 0, used fuel = 5
Input: locations = [5,2,1], start = 0, finish = 2, fuel = 3 Output: 0 Explanation: It's impossible to get from 0 to 2 using only 3 units of fuel since the shortest route needs 4 units of fuel.
Input: locations = [2,1,5], start = 0, finish = 0, fuel = 3 Output: 2 Explanation: There are two possible routes, 0 and 0 -> 1 -> 0.
Input: locations = [1,2,3], start = 0, finish = 2, fuel = 40 Output: 615088286 Explanation: The total number of possible routes is 2615088300. Taking this number modulo 10^9 + 7 gives us 615088286.
2 <= locations.length <= 100
1 <= locations[i] <= 10^9
- All integers in
locations
are distinct.0 <= start, finish < locations.length
1 <= fuel <= 200
- mine
- Java
- ``
- ``
- Java
- the most votes
Recursive & Memorize
Runtime: 123 ms, faster than 50.00%, Memory Usage: 39.3 MB, less than 50.00% of Java online submissions
// O(N^2 * K)time // O(N * K)space public int countRoutes(int[] locations, int start, int finish, int fuel) { int n = locations.length; long[][] dp = new long[n][fuel + 1]; for (int i = 0; i < n; ++i) { Arrays.fill(dp[i], -1); } return (int) solve(locations, start, finish, dp, fuel); } // dp[curCity][fuel] = number of ways to reach finish, when we are at city `curCity` with fuel `fuel` private long solve(int[] locations, int curCity, int e, long[][] dp, int fuel) { // 4. There is no further way left. if (fuel < 0) return 0; if (dp[curCity][fuel] != -1) return dp[curCity][fuel]; // 3. Now, if we have atleast 1 way of reaching `end`, add 1 to the answer. But don't stop right here, keep going, there might be more ways :) long ans = (curCity == e) ? 1 : 0; for (int nextCity = 0; nextCity < locations.length; ++nextCity) { // 1. Visit all cities except `curCity`. if (nextCity != curCity) { // 2. Continue this process recursively. ans = (ans + solve(locations, nextCity, e, dp, fuel - Math.abs(locations[curCity] - locations[nextCity]))) % 1000000007; } } return dp[curCity][fuel] = ans; }
DFS & Memorize
Runtime: 237 ms, faster than 19.77%,Memory Usage: 44.4 MB, less than 14.85% of Java online submissions
long MOD = 1000000007; Map<Long, Long> mem = new HashMap<>(); public int countRoutes(int[] locations, int start, int finish, int fuel) { return (int) (dfs(locations, start, finish, fuel) % MOD); } public long dfs(int[] l, int s, int f, int fuel) { long key = s * 1000000 + f * 1000 + fuel; if (mem.containsKey(key)) return mem.get(key); long cnt = 0; if (s == f) cnt++; for (int j = 0; j < l.length; j++) { int left = fuel - Math.abs(l[j] - l[s]); if (j != s && left >= 0) { cnt += dfs(l, j, f, left); } } cnt %= MOD; mem.put(key, cnt); return cnt; }
DP
Runtime: 442 ms, faster than 50.00%, Memory Usage: 39.2 MB, less than 50.00% of Java online submissions
// O(N^2 * K)time // O(N * K)space //dp[i][j] is the count we go to location i use j fuel. //the res = dp[finish][0] + dp[finish][1] + .. + dp[finish][fuel] long[][] dp = new long[101][201]; long mod = 1_000_000_007; public int countRoutes(int[] loc, int start, int finish, int fuel) { int n = loc.length; dp[start][0] = 1; for (int k = 0; k < fuel; k++) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (j == i) continue; int dis = Math.abs(loc[i] - loc[j]); if (k + dis > 200) continue; dp[j][k + dis] += dp[i][k]; dp[j][k + dis] %= mod; } } } long res = 0; for (int k = 0; k <= fuel; k++) { res += dp[finish][k]; res %= mod; } return (int) res; }