💥💥 Beats 100% on runtime and memory [EXPLAINED]
IntuitionStart by creating a DP table to store intermediate results. Each entry in the DP table represents the number of valid ways to form pairs up to a certai
# Intuition
Start by creating a DP table to store intermediate results. Each entry in the DP table represents the number of valid ways to form pairs up to a certain number in the list. This helps us build on previous results to find the final answer.

# Approach
Initialize the first row of the DP table to represent valid pairs up to the first number, then iteratively calculate the number of valid ways to form pairs for each number using values from the previous row and apply the constraints. Finally, we sum up the results in the last row to get the final answer.

# Complexity
- Time complexity:
O(n * m), where n is the number of elements in the input array and m is the maximum value in the array. This is because we iterate over the array and for each element, we fill in a DP table of size m. 

- Space complexity:
O(n * m) due to the DP table used to store the results for each element and each possible pair value.

# Code
```kotlin []
class Solution {
    val mod = 1e9.toInt() + 7

    fun countOfPairs(nums: IntArray): Int {
        val n = nums.size
        val dp = Array(n) { IntArray(1001) }
        for (i in 0..nums[0]) {
            dp[0][i] = 1
        }
        for (i in 1 until n) {
            var ways = 0
            var prev = 0
            for (cur in 0..nums[i]) {
                if (prev <= minOf(cur, cur - nums[i] + nums[i - 1])) {
                    ways = (ways + dp[i - 1][prev]) % mod
                    prev++
                }
                dp[i][cur] = ways
            }
        }

        var ans = 0
        for (i in 0 until 1001) {
            ans = (ans + dp[n - 1][i]) % mod
        }
        return ans
    }
}

```
['Array', 'Math', 'Binary Search', 'Dynamic Programming', 'Memoization', 'Combinatorics', 'Prefix Sum', 'Kotlin']