Build Array Where You Can Find The Maximum Exactly K Comparisons
HardUpdated: Aug 2, 2025
Practice on:
Problem
You are given three integers n, m and k. Consider the following algorithm to find the maximum element of an array of positive integers:
maximum_value = -1
maximum_index = -1
search_cost = 0
n = arr. length
for (1 = 0; i < n; i++) {
if (maximum_value ‹ arr[i]) {
maximum_value = arr [1]
maximum_index = i
search_cost = search_cost + 1
}
}
return maximum_index
You should build the array arr which has the following properties:
arrhas exactlynintegers.1 <= arr[i] <= mwhere(0 <= i < n).- After applying the mentioned algorithm to
arr, the valuesearch_costis equal tok.
Return the number of ways to build the array arr under the mentioned conditions. As the answer may grow large, the answer must be computed modulo 10^9 + 7.
Examples
Example 1
Input: n = 2, m = 3, k = 1
Output: 6
Explanation: The possible arrays are [1, 1], [2, 1], [2, 2], [3, 1], [3, 2] [3, 3]
Example 2
Input: n = 5, m = 2, k = 3
Output: 0
Explanation: There are no possible arrays that satisfy the mentioned conditions.
Example 3
Input: n = 9, m = 1, k = 1
Output: 1
Explanation: The only possible array is [1, 1, 1, 1, 1, 1, 1, 1, 1]
Solution
Method 1 – Dynamic Programming with State Compression
Intuition
We use dynamic programming to count the number of ways to build the array. The key is to track, for each position, the current maximum and the number of times the maximum has changed (i.e., the search cost). For each new element, we either keep the current maximum or increase it, incrementing the search cost.
Approach
- Define a DP table
dp[i][j][c]:i: current length of the array (from 0 to n)j: current maximum value in the array (from 0 to m)c: current search cost (from 0 to k)
- Initialize
dp[0][0][0] = 1(empty array, no max, no cost). - For each position
ifrom 0 to n-1:- For each possible current max
j(0 to m):- For each possible cost
c(0 to k):- For each possible next value
x(1 to m):- If
x > j, increment cost (c+1) and set new max tox. - Else, keep cost and max.
- If
- For each possible next value
- For each possible cost
- For each possible current max
- The answer is the sum of all
dp[n][j][k]forjin 1 to m. - Use modulo
10^9 + 7for all operations.
Code
C++
class Solution {
public:
int numOfArrays(int n, int m, int k) {
const int MOD = 1e9 + 7;
vector<vector<vector<int>>> dp(n+1, vector<vector<int>>(m+1, vector<int>(k+1, 0)));
dp[0][0][0] = 1;
for (int i = 0; i < n; ++i) {
for (int mx = 0; mx <= m; ++mx) {
for (int c = 0; c <= k; ++c) {
if (dp[i][mx][c] == 0) continue;
for (int x = 1; x <= m; ++x) {
if (x > mx && c+1 <= k)
dp[i+1][x][c+1] = (dp[i+1][x][c+1] + dp[i][mx][c]) % MOD;
else if (x <= mx)
dp[i+1][mx][c] = (dp[i+1][mx][c] + dp[i][mx][c]) % MOD;
}
}
}
}
int ans = 0;
for (int mx = 1; mx <= m; ++mx)
ans = (ans + dp[n][mx][k]) % MOD;
return ans;
}
};
Go
func numOfArrays(n int, m int, k int) int {
MOD := int(1e9 + 7)
dp := make([][][]int, n+1)
for i := range dp {
dp[i] = make([][]int, m+1)
for j := range dp[i] {
dp[i][j] = make([]int, k+1)
}
}
dp[0][0][0] = 1
for i := 0; i < n; i++ {
for mx := 0; mx <= m; mx++ {
for c := 0; c <= k; c++ {
if dp[i][mx][c] == 0 {
continue
}
for x := 1; x <= m; x++ {
if x > mx && c+1 <= k {
dp[i+1][x][c+1] = (dp[i+1][x][c+1] + dp[i][mx][c]) % MOD
} else if x <= mx {
dp[i+1][mx][c] = (dp[i+1][mx][c] + dp[i][mx][c]) % MOD
}
}
}
}
}
ans := 0
for mx := 1; mx <= m; mx++ {
ans = (ans + dp[n][mx][k]) % MOD
}
return ans
}
Java
class Solution {
public int numOfArrays(int n, int m, int k) {
int MOD = 1_000_000_007;
int[][][] dp = new int[n+1][m+1][k+1];
dp[0][0][0] = 1;
for (int i = 0; i < n; i++) {
for (int mx = 0; mx <= m; mx++) {
for (int c = 0; c <= k; c++) {
if (dp[i][mx][c] == 0) continue;
for (int x = 1; x <= m; x++) {
if (x > mx && c+1 <= k)
dp[i+1][x][c+1] = (dp[i+1][x][c+1] + dp[i][mx][c]) % MOD;
else if (x <= mx)
dp[i+1][mx][c] = (dp[i+1][mx][c] + dp[i][mx][c]) % MOD;
}
}
}
}
int ans = 0;
for (int mx = 1; mx <= m; mx++)
ans = (ans + dp[n][mx][k]) % MOD;
return ans;
}
}
Kotlin
class Solution {
fun numOfArrays(n: Int, m: Int, k: Int): Int {
val MOD = 1_000_000_007
val dp = Array(n+1) { Array(m+1) { IntArray(k+1) } }
dp[0][0][0] = 1
for (i in 0 until n) {
for (mx in 0..m) {
for (c in 0..k) {
if (dp[i][mx][c] == 0) continue
for (x in 1..m) {
if (x > mx && c+1 <= k)
dp[i+1][x][c+1] = (dp[i+1][x][c+1] + dp[i][mx][c]) % MOD
else if (x <= mx)
dp[i+1][mx][c] = (dp[i+1][mx][c] + dp[i][mx][c]) % MOD
}
}
}
}
var ans = 0
for (mx in 1..m)
ans = (ans + dp[n][mx][k]) % MOD
return ans
}
}
Python
class Solution:
def numOfArrays(self, n: int, m: int, k: int) -> int:
MOD = 10**9 + 7
dp: list[list[list[int]]] = [[[0] * (k+1) for _ in range(m+1)] for _ in range(n+1)]
dp[0][0][0] = 1
for i in range(n):
for mx in range(m+1):
for c in range(k+1):
if dp[i][mx][c] == 0:
continue
for x in range(1, m+1):
if x > mx and c+1 <= k:
dp[i+1][x][c+1] = (dp[i+1][x][c+1] + dp[i][mx][c]) % MOD
elif x <= mx:
dp[i+1][mx][c] = (dp[i+1][mx][c] + dp[i][mx][c]) % MOD
ans = 0
for mx in range(1, m+1):
ans = (ans + dp[n][mx][k]) % MOD
return ans
Rust
impl Solution {
pub fn num_of_arrays(n: i32, m: i32, k: i32) -> i32 {
const MOD: i32 = 1_000_000_007;
let (n, m, k) = (n as usize, m as usize, k as usize);
let mut dp = vec![vec![vec![0; k+1]; m+1]; n+1];
dp[0][0][0] = 1;
for i in 0..n {
for mx in 0..=m {
for c in 0..=k {
let val = dp[i][mx][c];
if val == 0 { continue; }
for x in 1..=m {
if x > mx && c+1 <= k {
dp[i+1][x][c+1] = (dp[i+1][x][c+1] + val) % MOD;
} else if x <= mx {
dp[i+1][mx][c] = (dp[i+1][mx][c] + val) % MOD;
}
}
}
}
}
let mut ans = 0;
for mx in 1..=m {
ans = (ans + dp[n][mx][k]) % MOD;
}
ans
}
}
Complexity
- ⏰ Time complexity:
O(n * m * m * k)(can be optimized toO(n * m * k)with prefix sums) - 🧺 Space complexity:
O(n * m * k)