硬币路径
Given an array
A(index starts at1) consisting of N integers: A1, A2, ..., AN and an integerB. The integerBdenotes that from any place (suppose the index isi) in the arrayA, you can jump to any one of the place in the arrayAindexedi+1,i+2, …,i+Bif this place can be jumped to. Also, if you step on the indexi, you have to pay Ai coins. If Ai is -1, it means you can’t jump to the place indexediin the array.Now, you start from the place indexed
1in the arrayA, and your aim is to reach the place indexedNusing the minimum coins. You need to return the path of indexes (starting from 1 to N) in the array you should take to get to the place indexedNusing minimum coins.If there are multiple paths with the same cost, return the lexicographically smallest such path.
If it's not possible to reach the place indexed N then you need to return an empty array.
Example 1:
Input: [1,2,4,-1,2], 2 Output: [1,3,5]Example 2:
Input: [1,2,4,-1,2], 1 Output: []Note:
- Path Pa1, Pa2, ..., Pan is lexicographically smaller than Pb1, Pb2, ..., Pbm, if and only if at the first
iwhere Pai and Pbi differ, Pai < Pbi; when no suchiexists, thenn<m.- A1 >= 0. A2, ..., AN (if exist) will in the range of [-1, 100].
- Length of A is in the range of [1, 1000].
- B is in the range of [1, 100].
vector<int> cheapestJump(vector<int>& A, int B) {
// "两条路径代价相同时,取词典序小的那个"
// 设dp[i]表示从A[i..]起跳的最小代价,在dp[i]按序尝试i+1,i+2,...,i+B,先找到的最小代价字典序就小。
// dp[i] = min{ A[i] + dp[i+b] },1<=b<=B;初始dp[N-1] = 0
const int N = A.size();
vector<int> dp(N, INT_MAX);
dp[N-1] = 0;
vector<int> next(N, -1); // 记录路径
for (int i = N - 2; i >= 0; i--) {
if (A[i] == -1) continue;
int maxJ = min(i + B, N - 1);
for (int j = i + 1; j <= maxJ; j++) {
if (A[j] == -1) continue;
int cost = A[i] + dp[j];
if (cost < dp[i]) {
dp[i] = cost;
next[i] = j;
}
}
}
vector<int> ans;
// for (p = head; p != NULL; p = p->next)
for (int i = 0; i != -1; i = next[i]) {
ans.push_back(i + 1); // 1-indexed
if (i == N - 1) return ans;
}
return {};
}