// Time: O(n) // Space: O(n) // dp, mono deque class Solution { public: int minimumCoins(vector& prices) { vector dp(size(prices) + 1, numeric_limits::max()); dp[0] = 0; deque dq; for (int i = 0, j = 0; i < size(prices); ++i) { while (!empty(dq) && dp[dq.back()] + prices[dq.back()] >= dp[i] + prices[i]) { dq.pop_back(); } dq.emplace_back(i); for (; j + (j + 1) < i; ++j) { assert(!empty(dq)); if (dq.front() == j) { dq.pop_front(); } } dp[i + 1] = dp[dq.front()] + prices[dq.front()]; } return dp.back(); } }; // Time: O(nlogn) // Space: O(n) // dp, bst class Solution2 { public: int minimumCoins(vector& prices) { vector dp(size(prices) + 1, numeric_limits::max()); dp[0] = 0; set> bst; for (int i = 0, j = 0; i < size(prices); ++i) { bst.emplace(dp[i] + prices[i], i); for (; j + (j + 1) < i; ++j) { bst.erase(pair(dp[j] + prices[j], j)); } dp[i + 1] = dp[cbegin(bst)->second] + prices[cbegin(bst)->second]; } return dp.back(); } };