N 大小数组的计数,每个元素是其邻居的倍数或除数
给定两个数字N和K ,任务是计算大小为N的所有可能数组的数量,使得每个元素都是小于或等于K的正整数,并且是其邻居的倍数或除数。由于答案可能很大,因此以10 9 + 7为模打印。
例子:
Input: N = 2, K = 3
Output: 7
Explanation: All the possible arrays are – { {1, 2}, {2, 1}, {1, 3}, {3, 1}, {1, 1}, {2, 2}, {3, 3} }
Input: N = 5, K = 4
Output: 380
朴素方法:最简单的方法是查找大小为 N 的数组的所有组合,其中每个元素小于或等于“K”,并为每个组合检查相邻元素是否为彼此的倍数。
时间复杂度: O(K N * N)
辅助空间: O(N)
有效方法:上述方法也可以通过使用动态规划来优化,因为它的重叠子问题和最佳子结构属性使用以下观察:
The subproblems can be stored in dp[][] table using memoization where dp[i][prev] stores the count of all possible arrays from the ith position till the end, with prev as the value in (i-t)th index.
请按照以下步骤解决问题:
- 初始化一个全局多维数组dp[][]来存储每次递归调用的结果。
- 找出从1到K的所有数的倍数和除数并将它们存储起来。
- 定义一个递归函数并执行以下操作:
- 如果i的值为N ,则返回1作为有效数组已形成。
- 如果已计算状态dp[i][prev]的结果,则返回该计算值。
- 遍历“ prev ”的所有倍数和除数,并为每个数字调用第(i + 1) 个索引的递归函数。
- dp[0][1]处的值将是必需的答案。
以下是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Declaring a DP array
int dp[1005][1005];
// Vector of Vector for
// storing all the factors and
// multiples of a number
vector > info(1005);
// Function to find the count
// of arrays such that each
// element is a multiple or
// divisor of its neighbours.
int countOfArrays(int index, int prev, int N)
{
// If i = N, return 1 as
// a valid array has been constructed.
if (index == N) {
return 1;
}
// If the state is already computed
if (dp[index][prev] != -1) {
return dp[index][prev];
}
dp[index][prev] = 0;
// Iterate through all the factors and
// multiples of the previous number
for (auto num : info[prev]) {
// Call the function
// for index 'i + 1'.
dp[index][prev]
+= countOfArrays(index + 1,
num, N);
// Taking the remainder modulo 1e9+7.
dp[index][prev] %= 1000000007;
}
// Return the answer.
return dp[index][prev];
}
// Utility function to find
// the count of arrays such that
// each element is a multiple
// or divisor of its neighbours.
int UtilCountOfArrays(int N, int K)
{
// Initialize the DP array with -1.
memset(dp, -1, sizeof dp);
// Finding the divisors and multiples
// till 'K', for all numbers from 1 to K
for (int i = 1; i <= K; ++i) {
for (int j = 1; j <= K; ++j) {
if (i % j == 0 or j % i == 0) {
info[i].push_back(j);
}
}
}
// Function call.
return countOfArrays(0, 1, N);
}
// Driver code.
int main()
{
// Input variables.
int N = 2;
int K = 3;
cout << UtilCountOfArrays(N, K) << endl;
return 0;
}
Java
import java.util.*;
class GFG {
// Declaring a DP array
static int[][] dp = new int[1005][1005];
// Vector of Vector for
// storing all the factors and
// multiples of a number
static ArrayList > info
= new ArrayList >();
// Function to find the count
// of arrays such that each
// element is a multiple or
// divisor of its neighbours.
public static int countOfArrays(int index, int prev,
int N)
{
// If i = N, return 1 as
// a valid array has been constructed.
if (index == N) {
return 1;
}
// If the state is already computed
if (dp[index][prev] != -1) {
return dp[index][prev];
}
dp[index][prev] = 0;
// Iterate through all the factors and
// multiples of the previous number
for (int num = 0; num < info.get(prev).size();
num++) {
// Call the function
// for index 'i + 1'.
dp[index][prev] += countOfArrays(
index + 1, info.get(prev).get(num), N);
// Taking the remainder modulo 1e9+7.
dp[index][prev] %= 1000000007;
}
// Return the answer.
return dp[index][prev];
}
// Utility function to find
// the count of arrays such that
// each element is a multiple
// or divisor of its neighbours.
public static int UtilCountOfArrays(int N, int K)
{
// Initialize the DP array with -1.
for (int i = 0; i < 1005; i++) {
for (int j = 0; j < 1005; j++) {
dp[i][j] = -1;
}
}
// Declaring info size
for (int i = 0; i < 1005; i++) {
ArrayList temp
= new ArrayList();
info.add(temp);
}
// Finding the divisors and multiples
// till 'K', for all numbers from 1 to K
for (int i = 1; i <= K; ++i) {
for (int j = 1; j <= K; ++j) {
if ((i % j == 0) || (j % i == 0)) {
info.get(i).add(j);
}
}
}
// Function call.
return countOfArrays(0, 1, N);
}
public static void main(String[] args)
{
// Input variables.
int N = 2;
int K = 3;
System.out.println(UtilCountOfArrays(N, K));
}
}
// This code is contributed by ninja_hattori.
Python3
# pyprogram for the above approach
# Declaring a DP array
dp = [[-1 for _ in range(1005)] for _ in range(1005)]
# Vector of Vector for
# storing all the factors and
# multiples of a number
info = [[] for _ in range(1005)]
# Function to find the count
# of arrays such that each
# element is a multiple or
# divisor of its neighbours.
def countOfArrays(index, prev, N):
# If i = N, return 1 as
# a valid array has been constructed.
if (index == N):
return 1
# If the state is already computed
if (dp[index][prev] != -1):
return dp[index][prev]
dp[index][prev] = 0
# Iterate through all the factors and
# multiples of the previous number
for num in info[prev]:
# Call the function
# for index 'i + 1'.
dp[index][prev] += countOfArrays(index + 1, num, N)
# Taking the remainder modulo 1e9+7.
dp[index][prev] %= 1000000007
# Return the answer.
return dp[index][prev]
# Utility function to find
# the count of arrays such that
# each element is a multiple
# or divisor of its neighbours.
def UtilCountOfArrays(N, K):
# Initialize the DP array with -1.
# Finding the divisors and multiples
# till 'K', for all numbers from 1 to K
for i in range(1, K+1):
for j in range(1, K+1):
if (i % j == 0 or j % i == 0):
info[i].append(j)
# Function call.
return countOfArrays(0, 1, N)
# Driver code.
if __name__ == "__main__":
# Input variables.
N = 2
K = 3
print(UtilCountOfArrays(N, K))
# This code is contributed by rakeshsahni
Javascript
7
时间复杂度: O(N * K * √K)
辅助空间: O(N * K)