<p>You are given an array of <strong>positive</strong> integers <code>nums</code> of length <code>n</code>.</p>

<p>We call a pair of <strong>non-negative</strong> integer arrays <code>(arr1, arr2)</code> <strong>monotonic</strong> if:</p>

<ul>
	<li>The lengths of both arrays are <code>n</code>.</li>
	<li><code>arr1</code> is monotonically <strong>non-decreasing</strong>, in other words, <code>arr1[0] &lt;= arr1[1] &lt;= ... &lt;= arr1[n - 1]</code>.</li>
	<li><code>arr2</code> is monotonically <strong>non-increasing</strong>, in other words, <code>arr2[0] &gt;= arr2[1] &gt;= ... &gt;= arr2[n - 1]</code>.</li>
	<li><code>arr1[i] + arr2[i] == nums[i]</code> for all <code>0 &lt;= i &lt;= n - 1</code>.</li>
</ul>

<p>Return the count of <strong>monotonic</strong> pairs.</p>

<p>Since the answer may be very large, return it <strong>modulo</strong> <code>10<sup>9</sup> + 7</code>.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">nums = [2,3,2]</span></p>

<p><strong>Output:</strong> <span class="example-io">4</span></p>

<p><strong>Explanation:</strong></p>

<p>The good pairs are:</p>

<ol>
	<li><code>([0, 1, 1], [2, 2, 1])</code></li>
	<li><code>([0, 1, 2], [2, 2, 0])</code></li>
	<li><code>([0, 2, 2], [2, 1, 0])</code></li>
	<li><code>([1, 2, 2], [1, 1, 0])</code></li>
</ol>
</div>

<p><strong class="example">Example 2:</strong></p>

<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">nums = [5,5,5,5]</span></p>

<p><strong>Output:</strong> <span class="example-io">126</span></p>
</div>

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

<ul>
	<li><code>1 &lt;= n == nums.length &lt;= 2000</code></li>
	<li><code>1 &lt;= nums[i] &lt;= 1000</code></li>
</ul>

class Solution:
    def countOfPairs(self, nums: List[int]) -> int:
        modulo = 1000000007
        n = len(nums)
        curr = 0 
        upper = nums[0]
        base = [0]
        for i in range(1, len(nums)):
            if nums[i] < curr:
                return 0
            if nums[i] - curr > upper:
                curr = nums[i] - upper 
                base.append(curr)
            if nums[i] - curr == upper:
                base.append(curr)
            if nums[i] - curr < upper:
                upper = nums[i] - curr 
                base.append(curr)
        answers = []
        prefix_sums = []
        for i in range(len(nums)):
            answers.append([0 for i in range(1001)])
            prefix_sums.append([])
        for i in range(1001):
            if i < base[n-1]:
                continue 
            if nums[n-1] - i >= 0:
                answers[n-1][i] = 1 
        self.calculate_prefix_sum(answers, prefix_sums, n-1)
        for i in range(n-2, -1, -1):
            for j in range(1001):
                if j < base[i]:
                    continue 
                second_elem = nums[i] - j 
                next_elem = nums[i+1] - second_elem 
                lower_bound = max(j, next_elem)
                answers[i][j] = (prefix_sums[i+1][-1] - prefix_sums[i+1][min(lower_bound, 1001)]) % modulo 
            self.calculate_prefix_sum(answers, prefix_sums, i)
        return prefix_sums[0][-1]
        
    def calculate_prefix_sum(self, answers, prefix_sums, n):
        modulo = 1000000007
        curr = 0 
        for i in range(1001):
            prefix_sums[n].append(curr)
            curr += answers[n][i]
            curr %= modulo
        prefix_sums[n].append(curr)
    

        
177762