[
game
dp
math
array
]
Leetcode 1690. Stone Game VII
Problem statement
https://leetcode.com/problems/stone-game-vii/
Solution
We can see dynamic programming structure in this problem: each time we take some stones from the left or from the left side, what is rest is always contigious array. So, let us denote by dp(i, j) the biggest difference in scores for the person who start with this position.
- If
i > j, then we have empty array and result is zero. - In the opposite case, we have two options: we can take either leftmost stone or rightmost stone. We also precomputed
CSum: cumulative sums to evaluate sums in ranges inO(1)time. We can either can gain sum from[i+1, j]and subtractdp(i+1, j)or we can gain sum from[i, j-1]and subtractdp(i, j-1). Why we need to subtract here? Becausedp(i+1, j)anddp(i, j-1)is maximum difference of scores another player can gain, so for current player we need to take negative value.
Complexity
We have O(n^2) states with 2 transactions from every state, so total time and space is O(n^2).
Code
class Solution:
def stoneGameVII(self, A):
CSum = [0] + list(accumulate(A))
@lru_cache(2000)
def dp(i, j):
if i > j: return 0
sm = CSum[j + 1] - CSum[i]
return sm - min(A[i] + dp(i+1, j), A[j] + dp(i, j-1))
return dp(0, len(A) - 1)
Important remark
Sometimes when we use lru_cache, it works slower than memoisation by hands, and in this problem you will get TLE if you use usual @lru_cache(None), because restrictions in this problem are quite tight on python. So, what you can do during contest to avoid this?
- Do memorisation by hands: it is the quickest and working way to do it: instead of
lru_cache, use say dictionarydand each time in the beginning check if we have element indor not. - Change
Noneinlru_cacheto some magical constant, here1000to10000will work fine, but I do not have explanation why. And on the contest you can not be lucky to get it or you get it and then it will be rejudged and you will get TLE or MLE. So, it is not safe in my opinion. - Use classical table dp, where you have here
2dlist of lists and then fill it with usual ways. It is also safe way, but I am so used tolru_cache, so for this one I would have spend more time on contest, but if method1is not working, you should definitely go to this one.