We need to count the number of monotonic pairs (arr1, arr2) where arr1 is non-decreasing, arr2 is non-increasing, and arr1[i] + arr2[i] = nums[i]. Unlike part I, here both arr1 and arr2 must be monotonic, so we need to track both the last value of arr1 and arr2 in our DP.
Let dp[i][a][b] be the number of ways to fill arr1[0..i] and arr2[0..i] where arr1[i]=a, arr2[i]=b, arr1 is non-decreasing, arr2 is non-increasing, and a+b=nums[i].
For each position, for each possible value of arr1[i] and arr2[i], sum over all valid previous (a’, b’) such that a’ <= a and b’ >= b.
Use prefix sums to speed up the DP transitions.
The answer is the sum over all valid dp[n-1][a][b] for a+b=nums[n-1].
classSolution:
defcountMonotonicPairs(self, nums: list[int]) -> int:
MOD =10**9+7 n = len(nums)
mx = max(nums)
dp = [[[0]*(mx+1) for _ in range(mx+1)] for _ in range(n)]
for a in range(nums[0]+1):
b = nums[0] - a
dp[0][a][b] =1for i in range(1, n):
for a in range(nums[i]+1):
b = nums[i] - a
if b <0or b > mx:
continuefor pa in range(a+1):
for pb in range(b, mx+1):
dp[i][a][b] = (dp[i][a][b] + dp[i-1][pa][pb]) % MOD
ans =0for a in range(nums[-1]+1):
b = nums[-1] - a
if0<= b <= mx:
ans = (ans + dp[n-1][a][b]) % MOD
return ans
classSolution {
public:int countMonotonicPairs(vector<int>& nums) {
constint MOD =1e9+7;
int n = nums.size(), mx =*max_element(nums.begin(), nums.end());
vector<vector<vector<int>>> dp(n, vector<vector<int>>(mx+1, vector<int>(mx+1, 0)));
for (int a =0; a <= nums[0]; ++a) {
int b = nums[0] - a;
dp[0][a][b] =1;
}
for (int i =1; i < n; ++i) {
for (int a =0; a <= nums[i]; ++a) {
int b = nums[i] - a;
if (b <0|| b > mx) continue;
for (int pa =0; pa <= a; ++pa) {
for (int pb = b; pb <= mx; ++pb) {
dp[i][a][b] = (dp[i][a][b] + dp[i-1][pa][pb]) % MOD;
}
}
}
}
int ans =0;
for (int a =0; a <= nums[n-1]; ++a) {
int b = nums[n-1] - a;
if (b <0|| b > mx) continue;
ans = (ans + dp[n-1][a][b]) % MOD;
}
return ans;
}
};
classSolution {
publicintcountMonotonicPairs(int[] nums) {
int MOD = 1_000_000_007, n = nums.length, mx = 0;
for (int v : nums) mx = Math.max(mx, v);
int[][][] dp =newint[n][mx+1][mx+1];
for (int a = 0; a <= nums[0]; ++a) {
int b = nums[0]- a;
dp[0][a][b]= 1;
}
for (int i = 1; i < n; ++i) {
for (int a = 0; a <= nums[i]; ++a) {
int b = nums[i]- a;
if (b < 0 || b > mx) continue;
for (int pa = 0; pa <= a; ++pa) {
for (int pb = b; pb <= mx; ++pb) {
dp[i][a][b]= (dp[i][a][b]+ dp[i-1][pa][pb]) % MOD;
}
}
}
}
int ans = 0;
for (int a = 0; a <= nums[n-1]; ++a) {
int b = nums[n-1]- a;
if (b < 0 || b > mx) continue;
ans = (ans + dp[n-1][a][b]) % MOD;
}
return ans;
}
}
classSolution {
funcountMonotonicPairs(nums: IntArray): Int {
val MOD = 1_000_000_007
val n = nums.size
val mx = nums.maxOrNull() ?:0val dp = Array(n) { Array(mx+1) { IntArray(mx+1) } }
for (a in0..nums[0]) {
val b = nums[0] - a
dp[0][a][b] = 1 }
for (i in1 until n) {
for (a in0..nums[i]) {
val b = nums[i] - a
if (b < 0|| b > mx) continuefor (pa in0..a) {
for (pb in b..mx) {
dp[i][a][b] = (dp[i][a][b] + dp[i-1][pa][pb]) % MOD
}
}
}
}
var ans = 0for (a in0..nums[n-1]) {
val b = nums[n-1] - a
if (b < 0|| b > mx) continue ans = (ans + dp[n-1][a][b]) % MOD
}
return ans
}
}
impl Solution {
pubfncount_monotonic_pairs(nums: Vec<i32>) -> i32 {
constMOD: i32=1_000_000_007;
let n = nums.len();
let mx =*nums.iter().max().unwrap() asusize;
letmut dp =vec![vec![vec![0; mx+1]; mx+1]; n];
for a in0..=nums[0] asusize {
let b = nums[0] asusize- a;
dp[0][a][b] =1;
}
for i in1..n {
for a in0..=nums[i] asusize {
let b = nums[i] asusize- a;
if b > mx { continue; }
for pa in0..=a {
for pb in b..=mx {
dp[i][a][b] = (dp[i][a][b] + dp[i-1][pa][pb]) %MOD;
}
}
}
}
letmut ans =0;
for a in0..=nums[n-1] asusize {
let b = nums[n-1] asusize- a;
if b > mx { continue; }
ans = (ans + dp[n-1][a][b]) %MOD;
}
ans
}
}