<p>You are given an <code>m x n</code> integer matrix <code>points</code> (<strong>0-indexed</strong>). Starting with <code>0</code> points, you want to <strong>maximize</strong> the number of points you can get from the matrix.</p>

<p>To gain points, you must pick one cell in <strong>each row</strong>. Picking the cell at coordinates <code>(r, c)</code> will <strong>add</strong> <code>points[r][c]</code> to your score.</p>

<p>However, you will lose points if you pick a cell too far from the cell that you picked in the previous row. For every two adjacent rows <code>r</code> and <code>r + 1</code> (where <code>0 &lt;= r &lt; m - 1</code>), picking cells at coordinates <code>(r, c<sub>1</sub>)</code> and <code>(r + 1, c<sub>2</sub>)</code> will <strong>subtract</strong> <code>abs(c<sub>1</sub> - c<sub>2</sub>)</code> from your score.</p>

<p>Return <em>the <strong>maximum</strong> number of points you can achieve</em>.</p>

<p><code>abs(x)</code> is defined as:</p>

<ul>
	<li><code>x</code> for <code>x &gt;= 0</code>.</li>
	<li><code>-x</code> for <code>x &lt; 0</code>.</li>
</ul>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong><strong> </strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2021/07/12/screenshot-2021-07-12-at-13-40-26-diagram-drawio-diagrams-net.png" style="width: 300px; height: 300px;" />
<pre>
<strong>Input:</strong> points = [[1,2,3],[1,5,1],[3,1,1]]
<strong>Output:</strong> 9
<strong>Explanation:</strong>
The blue cells denote the optimal cells to pick, which have coordinates (0, 2), (1, 1), and (2, 0).
You add 3 + 5 + 3 = 11 to your score.
However, you must subtract abs(2 - 1) + abs(1 - 0) = 2 from your score.
Your final score is 11 - 2 = 9.
</pre>

<p><strong class="example">Example 2:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2021/07/12/screenshot-2021-07-12-at-13-42-14-diagram-drawio-diagrams-net.png" style="width: 200px; height: 299px;" />
<pre>
<strong>Input:</strong> points = [[1,5],[2,3],[4,2]]
<strong>Output:</strong> 11
<strong>Explanation:</strong>
The blue cells denote the optimal cells to pick, which have coordinates (0, 1), (1, 1), and (2, 0).
You add 5 + 3 + 4 = 12 to your score.
However, you must subtract abs(1 - 1) + abs(1 - 0) = 1 from your score.
Your final score is 12 - 1 = 11.
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>m == points.length</code></li>
	<li><code>n == points[r].length</code></li>
	<li><code>1 &lt;= m, n &lt;= 10<sup>5</sup></code></li>
	<li><code>1 &lt;= m * n &lt;= 10<sup>5</sup></code></li>
	<li><code>0 &lt;= points[r][c] &lt;= 10<sup>5</sup></code></li>
</ul>

'''
[
    [1,2,3], max = 3, occurs at c = 2
    [1,5,1], max = 5
    [3,1,1]] max = 3

for each value, check adding with which previous row's value will output the maximum

    [1,2,3], 
    [2,7,4],
    [9,8,7]
max value in our last row
O(mxnxn)

for each value, determine the current maximum we've seen
    [1,2,3,0]
    [2,7,4,0]
    [9,8,5,0], max = 9
    cur max = 3

    [3,1,3] max = 3, occurs at c= 0 and 2
    [2,2,5]

    [3,1,3]
    [5,4,8]

    cur max = 3
    [3,2,3]0
    [5,4,8]0
    look at values on top and r + 1, c + 1 but need to subtract - 1

[1,5],
[2,3],
[4,2]]

[1,5,0] cur max = 1
[6,8,0]
[11,10,0] => 11


for first row of dp matrix
    keep track of current maximum value (subtract 1 at each column iteration)
    if num is greater than cur max, fill that with our dp and update cur max
for rest of rows:
    compare adding value at i - 1 OR value at (i - 1, c + 1) - 1
'''

class Solution:
    def maxPoints(self, points: List[List[int]]) -> int:
        cols = len(points[0])
        previous_row = [0] * cols

        for row in points:
            # running_max holds the maximum value generated in the previous iteration of each loop
            running_max = 0

            # Left to right pass
            for col in range(cols):
                running_max = max(running_max - 1, previous_row[col])
                previous_row[col] = running_max

            running_max = 0
            # Right to left pass
            for col in range(cols - 1, -1, -1):
                running_max = max(running_max - 1, previous_row[col])
                previous_row[col] = (
                    max(previous_row[col], running_max) + row[col]
                )

        # Find maximum points in the last row
        return max(previous_row)
'''
[[1,5],[2,3],[4,2]]
m = 3, n = 2
[[1,5,0],[6,8,0],[11,10,0]]
first row:
j = 0
    cur max = 1
    cur max = 0
j = 1
    cur max = 5
    cur max = 4

i = 1
    j = 0
        2 + max(1, 5 - 1) = 6
    j = 1
        3 + max(5, 0 - 1) = 8
i = 2
    j = 0
        4 + max(6, 8 - 1) = 11
    j = 1
        2 + max(8, 0 - 1) = 10
    
'''
50300