Combinatorics
Dynamic Programming
Math
Number Theory
Description
You are given two integers n
and maxValue
, which are used to describe an ideal array.
A 0-indexed integer array arr
of length n
is considered ideal if the following conditions hold:
Every arr[i]
is a value from 1
to maxValue
, for 0 <= i < n
.
Every arr[i]
is divisible by arr[i - 1]
, for 0 < i < n
.
Return the number of distinct ideal arrays of length n
. Since the answer may be very large, return it modulo 109 + 7
.
Example 1:
Input: n = 2, maxValue = 5
Output: 10
Explanation: The following are the possible ideal arrays:
- Arrays starting with the value 1 (5 arrays): [1,1], [1,2], [1,3], [1,4], [1,5]
- Arrays starting with the value 2 (2 arrays): [2,2], [2,4]
- Arrays starting with the value 3 (1 array): [3,3]
- Arrays starting with the value 4 (1 array): [4,4]
- Arrays starting with the value 5 (1 array): [5,5]
There are a total of 5 + 2 + 1 + 1 + 1 = 10 distinct ideal arrays.
Example 2:
Input: n = 5, maxValue = 3
Output: 11
Explanation: The following are the possible ideal arrays:
- Arrays starting with the value 1 (9 arrays):
- With no other distinct values (1 array): [1,1,1,1,1]
- With 2nd distinct value 2 (4 arrays): [1,1,1,1,2], [1,1,1,2,2], [1,1,2,2,2], [1,2,2,2,2]
- With 2nd distinct value 3 (4 arrays): [1,1,1,1,3], [1,1,1,3,3], [1,1,3,3,3], [1,3,3,3,3]
- Arrays starting with the value 2 (1 array): [2,2,2,2,2]
- Arrays starting with the value 3 (1 array): [3,3,3,3,3]
There are a total of 9 + 1 + 1 = 11 distinct ideal arrays.
Constraints:
2 <= n <= 104
1 <= maxValue <= 104
Solutions
Solution 1: Dynamic Programming
Let \(f[i][j]\) represent the number of sequences ending with \(i\) and consisting of \(j\) distinct elements. The initial value is \(f[i][1] = 1\) .
Consider \(n\) balls, which are eventually divided into \(j\) parts. Using the "separator method," we can insert \(j-1\) separators into the \(n-1\) positions, and the number of combinations is \(c_{n-1}^{j-1}\) .
We can preprocess the combination numbers \(c[i][j]\) using the recurrence relation \(c[i][j] = c[i-1][j] + c[i-1][j-1]\) . Specifically, when \(j=0\) , \(c[i][j] = 1\) .
The final answer is:
\[
\sum\limits_{i=1}^{k}\sum\limits_{j=1}^{\log_2 k + 1} f[i][j] \times c_{n-1}^{j-1}
\]
where \(k\) represents the maximum value of the array, i.e., \(\textit{maxValue}\) .
Time Complexity : \(O(m \times \log^2 m)\)
Space Complexity : \(O(m \times \log m)\)
Python3 Java C++ Go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 class Solution :
def idealArrays ( self , n : int , maxValue : int ) -> int :
@cache
def dfs ( i , cnt ):
res = c [ - 1 ][ cnt - 1 ]
if cnt < n :
k = 2
while k * i <= maxValue :
res = ( res + dfs ( k * i , cnt + 1 )) % mod
k += 1
return res
c = [[ 0 ] * 16 for _ in range ( n )]
mod = 10 ** 9 + 7
for i in range ( n ):
for j in range ( min ( 16 , i + 1 )):
c [ i ][ j ] = 1 if j == 0 else ( c [ i - 1 ][ j ] + c [ i - 1 ][ j - 1 ]) % mod
ans = 0
for i in range ( 1 , maxValue + 1 ):
ans = ( ans + dfs ( i , 1 )) % mod
return ans
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 class Solution {
private int [][] f ;
private int [][] c ;
private int n ;
private int m ;
private static final int MOD = ( int ) 1e9 + 7 ;
public int idealArrays ( int n , int maxValue ) {
this . n = n ;
this . m = maxValue ;
this . f = new int [ maxValue + 1 ][ 16 ] ;
for ( int [] row : f ) {
Arrays . fill ( row , - 1 );
}
c = new int [ n ][ 16 ] ;
for ( int i = 0 ; i < n ; ++ i ) {
for ( int j = 0 ; j <= i && j < 16 ; ++ j ) {
c [ i ][ j ] = j == 0 ? 1 : ( c [ i - 1 ][ j ] + c [ i - 1 ][ j - 1 ] ) % MOD ;
}
}
int ans = 0 ;
for ( int i = 1 ; i <= m ; ++ i ) {
ans = ( ans + dfs ( i , 1 )) % MOD ;
}
return ans ;
}
private int dfs ( int i , int cnt ) {
if ( f [ i ][ cnt ] != - 1 ) {
return f [ i ][ cnt ] ;
}
int res = c [ n - 1 ][ cnt - 1 ] ;
if ( cnt < n ) {
for ( int k = 2 ; k * i <= m ; ++ k ) {
res = ( res + dfs ( k * i , cnt + 1 )) % MOD ;
}
}
f [ i ][ cnt ] = res ;
return res ;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 class Solution {
public :
int m , n ;
const int mod = 1e9 + 7 ;
vector < vector < int >> f ;
vector < vector < int >> c ;
int idealArrays ( int n , int maxValue ) {
this -> m = maxValue ;
this -> n = n ;
f . assign ( maxValue + 1 , vector < int > ( 16 , -1 ));
c . assign ( n , vector < int > ( 16 , 0 ));
for ( int i = 0 ; i < n ; ++ i )
for ( int j = 0 ; j <= i && j < 16 ; ++ j )
c [ i ][ j ] = ! j ? 1 : ( c [ i - 1 ][ j ] + c [ i - 1 ][ j - 1 ]) % mod ;
int ans = 0 ;
for ( int i = 1 ; i <= m ; ++ i ) ans = ( ans + dfs ( i , 1 )) % mod ;
return ans ;
}
int dfs ( int i , int cnt ) {
if ( f [ i ][ cnt ] != -1 ) return f [ i ][ cnt ];
int res = c [ n - 1 ][ cnt - 1 ];
if ( cnt < n )
for ( int k = 2 ; k * i <= m ; ++ k )
res = ( res + dfs ( k * i , cnt + 1 )) % mod ;
f [ i ][ cnt ] = res ;
return res ;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 func idealArrays ( n int , maxValue int ) int {
mod := int ( 1e9 ) + 7
m := maxValue
c := make ([][] int , n )
f := make ([][] int , m + 1 )
for i := range c {
c [ i ] = make ([] int , 16 )
}
for i := range f {
f [ i ] = make ([] int , 16 )
for j := range f [ i ] {
f [ i ][ j ] = - 1
}
}
var dfs func ( int , int ) int
dfs = func ( i , cnt int ) int {
if f [ i ][ cnt ] != - 1 {
return f [ i ][ cnt ]
}
res := c [ n - 1 ][ cnt - 1 ]
if cnt < n {
for k := 2 ; k * i <= m ; k ++ {
res = ( res + dfs ( k * i , cnt + 1 )) % mod
}
}
f [ i ][ cnt ] = res
return res
}
for i := 0 ; i < n ; i ++ {
for j := 0 ; j <= i && j < 16 ; j ++ {
if j == 0 {
c [ i ][ j ] = 1
} else {
c [ i ][ j ] = ( c [ i - 1 ][ j ] + c [ i - 1 ][ j - 1 ]) % mod
}
}
}
ans := 0
for i := 1 ; i <= m ; i ++ {
ans = ( ans + dfs ( i , 1 )) % mod
}
return ans
}
Solution 2
Python3 Java C++ Go TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 class Solution :
def idealArrays ( self , n : int , maxValue : int ) -> int :
c = [[ 0 ] * 16 for _ in range ( n )]
mod = 10 ** 9 + 7
for i in range ( n ):
for j in range ( min ( 16 , i + 1 )):
c [ i ][ j ] = 1 if j == 0 else ( c [ i - 1 ][ j ] + c [ i - 1 ][ j - 1 ]) % mod
f = [[ 0 ] * 16 for _ in range ( maxValue + 1 )]
for i in range ( 1 , maxValue + 1 ):
f [ i ][ 1 ] = 1
for j in range ( 1 , 15 ):
for i in range ( 1 , maxValue + 1 ):
k = 2
while k * i <= maxValue :
f [ k * i ][ j + 1 ] = ( f [ k * i ][ j + 1 ] + f [ i ][ j ]) % mod
k += 1
ans = 0
for i in range ( 1 , maxValue + 1 ):
for j in range ( 1 , 16 ):
ans = ( ans + f [ i ][ j ] * c [ - 1 ][ j - 1 ]) % mod
return ans
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 class Solution {
public int idealArrays ( int n , int maxValue ) {
final int mod = ( int ) 1e9 + 7 ;
int [][] c = new int [ n ][ 16 ] ;
for ( int i = 0 ; i < n ; ++ i ) {
for ( int j = 0 ; j <= i && j < 16 ; ++ j ) {
c [ i ][ j ] = j == 0 ? 1 : ( c [ i - 1 ][ j ] + c [ i - 1 ][ j - 1 ] ) % mod ;
}
}
long [][] f = new long [ maxValue + 1 ][ 16 ] ;
for ( int i = 1 ; i <= maxValue ; ++ i ) {
f [ i ][ 1 ] = 1 ;
}
for ( int j = 1 ; j < 15 ; ++ j ) {
for ( int i = 1 ; i <= maxValue ; ++ i ) {
int k = 2 ;
for (; k * i <= maxValue ; ++ k ) {
f [ k * i ][ j + 1 ] = ( f [ k * i ][ j + 1 ] + f [ i ][ j ] ) % mod ;
}
}
}
long ans = 0 ;
for ( int i = 1 ; i <= maxValue ; ++ i ) {
for ( int j = 1 ; j < 16 ; ++ j ) {
ans = ( ans + f [ i ][ j ] * c [ n - 1 ][ j - 1 ] ) % mod ;
}
}
return ( int ) ans ;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 class Solution {
public :
int idealArrays ( int n , int maxValue ) {
const int mod = 1e9 + 7 ;
vector < vector < int >> c ( n , vector < int > ( 16 ));
for ( int i = 0 ; i < n ; ++ i ) {
for ( int j = 0 ; j <= i && j < 16 ; ++ j ) {
if ( j == 0 ) {
c [ i ][ j ] = 1 ;
} else {
c [ i ][ j ] = ( c [ i - 1 ][ j ] + c [ i - 1 ][ j - 1 ]) % mod ;
}
}
}
vector < vector < long long >> f ( maxValue + 1 , vector < long long > ( 16 ));
for ( int i = 1 ; i <= maxValue ; ++ i ) {
f [ i ][ 1 ] = 1 ;
}
for ( int j = 1 ; j < 15 ; ++ j ) {
for ( int i = 1 ; i <= maxValue ; ++ i ) {
for ( int k = 2 ; k * i <= maxValue ; ++ k ) {
f [ k * i ][ j + 1 ] = ( f [ k * i ][ j + 1 ] + f [ i ][ j ]) % mod ;
}
}
}
long long ans = 0 ;
for ( int i = 1 ; i <= maxValue ; ++ i ) {
for ( int j = 1 ; j < 16 ; ++ j ) {
ans = ( ans + f [ i ][ j ] * c [ n - 1 ][ j - 1 ]) % mod ;
}
}
return ans ;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 func idealArrays ( n int , maxValue int ) ( ans int ) {
const mod = int ( 1e9 + 7 )
c := make ([][] int , n )
for i := 0 ; i < n ; i ++ {
c [ i ] = make ([] int , 16 )
for j := 0 ; j <= i && j < 16 ; j ++ {
if j == 0 {
c [ i ][ j ] = 1
} else {
c [ i ][ j ] = ( c [ i - 1 ][ j ] + c [ i - 1 ][ j - 1 ]) % mod
}
}
}
f := make ([][ 16 ] int , maxValue + 1 )
for i := 1 ; i <= maxValue ; i ++ {
f [ i ][ 1 ] = 1
}
for j := 1 ; j < 15 ; j ++ {
for i := 1 ; i <= maxValue ; i ++ {
for k := 2 ; k * i <= maxValue ; k ++ {
f [ k * i ][ j + 1 ] = ( f [ k * i ][ j + 1 ] + f [ i ][ j ]) % mod
}
}
}
for i := 1 ; i <= maxValue ; i ++ {
for j := 1 ; j < 16 ; j ++ {
ans = ( ans + f [ i ][ j ] * c [ n - 1 ][ j - 1 ]) % mod
}
}
return
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 function idealArrays ( n : number , maxValue : number ) : number {
const mod = 1e9 + 7 ;
const c : number [][] = Array . from ({ length : n }, () => Array ( 16 ). fill ( 0 ));
for ( let i = 0 ; i < n ; i ++ ) {
for ( let j = 0 ; j <= i && j < 16 ; j ++ ) {
if ( j === 0 ) {
c [ i ][ j ] = 1 ;
} else {
c [ i ][ j ] = ( c [ i - 1 ][ j ] + c [ i - 1 ][ j - 1 ]) % mod ;
}
}
}
const f : number [][] = Array . from ({ length : maxValue + 1 }, () => Array ( 16 ). fill ( 0 ));
for ( let i = 1 ; i <= maxValue ; i ++ ) {
f [ i ][ 1 ] = 1 ;
}
for ( let j = 1 ; j < 15 ; j ++ ) {
for ( let i = 1 ; i <= maxValue ; i ++ ) {
for ( let k = 2 ; k * i <= maxValue ; k ++ ) {
f [ k * i ][ j + 1 ] = ( f [ k * i ][ j + 1 ] + f [ i ][ j ]) % mod ;
}
}
}
let ans = 0 ;
for ( let i = 1 ; i <= maxValue ; i ++ ) {
for ( let j = 1 ; j < 16 ; j ++ ) {
ans = ( ans + f [ i ][ j ] * c [ n - 1 ][ j - 1 ]) % mod ;
}
}
return ans ;
}
GitHub