给定两个整数N和K ,任务是找到可以通过使用值0 、 1和2任意次数生成的N长度数组的数量,使得数组的所有相邻成对乘积的总和是K 。
例子:
Input: N = 4, K = 3
Output: 5
Explanation: All possible arrangements are:
- arr[] = {2, 1, 1, 0}, Adjacent pairwise product sum = 2 * 1 + 1 * 1 + 1 * 0 = 3.
- arr[] = {0, 2, 1, 1}, Adjacent pairwise product sum = 0 * 2 + 2 * 1 + 1 * 1 = 3.
- arr[] = {1, 1, 2, 0}, Adjacent pairwise product sum = 1 * 1 + 1 * 2 + 2 * 0 = 3.
- arr[] = {0, 1, 1, 2}, Adjacent pairwise product sum is 0 * 1 + 1 * 1 + 1 * 2 = 3.
- arr[] = {1, 1, 1, 1}, Adjacent pairwise product sum = 1*1 + 1*1 + 1*1 = 3.
Input: N = 10, K = 9
Output: 3445
朴素方法:最简单的方法是生成数组的所有可能排列,其值可以是0 、 1或2 ,并对相邻成对乘积和为K 的那些数组进行计数。打印此类安排的计数。
时间复杂度: O(N*3 N )
辅助空间: O(N)
高效的方法:为了优化上述方法,最佳思路是使用动态规划。重叠的子问题可以存储在dp[][][] 表中,其中dp[i][remaining][previous]存储从位置‘i’到位置(N – 1)的答案,其中‘remaining’作为要添加的剩余值和“前一个”作为放置在位置(i – 1) 中的数字。对于任何位置“i”,可能存在三种情况:
- 将“0”分配给位置“i”。
- 将“1”分配给位置“i”。
- 将“2”分配给位置“i”。
请按照以下步骤解决问题:
- 初始化dp[][][]以存储当前位置、要添加的剩余值和前一个位置的元素。
- 过渡状态如下:
dp[i][remaining_sum][previous_element] = dp(assign 0 to pos ‘i’) + dp(assign 1 to ‘i’ ) + dp(assign 2 to ‘i’)
- 递归求解上述递推关系,将每个状态的结果存入dp表。对于重叠,子问题使用dp 表中存储的结果。
- 在上述递归调用结束后,打印具有相邻成对积的数组总数为K的函数返回。
以下是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find total number of
// possible arrangements of array
int waysForPairwiseSumToBeK(
int i, int rem, int previous,
int N, int dp[][15][3])
{
// Base Case
if (i == N) {
if (rem == 0)
return 1;
else
return 0;
}
// If rem exceeds 'k' return 0
if (rem < 0)
return 0;
// Return the already calculated
// states
if (dp[i][rem][previous] != -1)
return dp[i][rem][previous];
int ways = 0;
// Place a '0' at current position
ways += waysForPairwiseSumToBeK(
i + 1, rem, 0, N, dp);
// Place a '1' at current position
// Add it to previous value
ways += waysForPairwiseSumToBeK(
i + 1, rem - (previous), 1, N, dp);
// Place a '2' at current position.
// Add it to previous value.
ways += waysForPairwiseSumToBeK(
i + 1, rem - (2 * previous), 2, N, dp);
// Store the current state result
// return the same result
return dp[i][rem][previous] = ways;
}
// Function to find number of possible
// arrangements of array with 0, 1, and
// 2 having pairwise product sum K
void countOfArrays(int i, int rem,
int previous, int N)
{
// Store the overlapping states
int dp[15][15][3];
// Initialize dp table with -1
memset(dp, -1, sizeof dp);
// Stores total number of ways
int totWays
= waysForPairwiseSumToBeK(
i, rem, previous, N, dp);
// Print number of ways
cout << totWays << ' ';
}
// Driver Code
int main()
{
// Given N and K
int N = 4, K = 3;
// Function Call
countOfArrays(0, K, 0, N);
return 0;
}
Java
// Java program for the
// above approach
import java.util.*;
class solution{
// Function to find total number of
// possible arrangements of array
static int waysForPairwiseSumToBeK(int i, int rem,
int previous,
int N, int [][][]dp)
{
// Base Case
if (i == N)
{
if (rem == 0)
return 1;
else
return 0;
}
// If rem exceeds
// 'k' return 0
if (rem < 0)
return 0;
// Return the already
// calculated states
if (dp[i][rem][previous] != -1)
return dp[i][rem][previous];
int ways = 0;
// Place a '0' at current position
ways += waysForPairwiseSumToBeK(i + 1, rem,
0, N, dp);
// Place a '1' at current position
// Add it to previous value
ways += waysForPairwiseSumToBeK(i + 1, rem -
(previous),
1, N, dp);
// Place a '2' at current position.
// Add it to previous value.
ways += waysForPairwiseSumToBeK(i + 1, rem -
(2 * previous),
2, N, dp);
// Store the current state result
// return the same result
dp[i][rem][previous] = ways;
return ways;
}
// Function to find number of possible
// arrangements of array with 0, 1, and
// 2 having pairwise product sum K
static void countOfArrays(int i, int rem,
int previous, int N)
{
// Store the overlapping states
int [][][]dp = new int[15][15][3];
// Initialize dp table with -1
for(int p = 0; p < 15; p++)
{
for(int q = 0; q < 15; q++)
{
for(int r = 0; r < 3; r++)
dp[p][q][r] = -1;
}
}
// Stores total number of ways
int totWays = waysForPairwiseSumToBeK(i, rem,
previous,
N, dp);
// Print number of ways
System.out.print(totWays);
}
// Driver Code
public static void main(String args[])
{
// Given N and K
int N = 4, K = 3;
// Function Call
countOfArrays(0, K, 0, N);
}
}
// This code is contributed by SURENDRA_GANGWAR
Python3
# Pyhton3 program for the above approach
# Function to find total number of
# possible arrangements of array
def waysForPairwiseSumToBeK(i, rem, previous, N, dp):
# Base Case
if (i == N):
if (rem == 0):
return 1
else:
return 0
# If rem exceeds 'k' return 0
if (rem < 0):
return 0
# Return the already calculated
# states
if (dp[i][rem][previous] != -1):
return dp[i][rem][previous]
ways = 0
# Place a '0' at current position
ways += waysForPairwiseSumToBeK(i + 1, rem,
0, N, dp)
# Place a '1' at current position
# Add it to previous value
ways += waysForPairwiseSumToBeK(i + 1,
rem - (previous),
1, N, dp)
# Place a '2' at current position.
# Add it to previous value.
ways += waysForPairwiseSumToBeK(i + 1,
rem - (2 * previous),
2, N, dp)
# Store the current state result
# return the same result
dp[i][rem][previous] = ways
return ways
# Function to find number of possible
# arrangements of array with 0, 1, and
# 2 having pairwise product sum K
def countOfArrays(i, rem, previous, N):
# Store the overlapping states
dp = [[[-1 for i in range(3)]
for j in range(15)]
for k in range(15)]
# Stores total number of ways
totWays = waysForPairwiseSumToBeK(i, rem,
previous,
N, dp)
# Print number of ways
print(totWays, end = " ")
# Driver Code
if __name__ == '__main__':
# Given N and K
N = 4
K = 3
# Function Call
countOfArrays(0, K, 0, N)
# This code is contributed by bgangwar59
C#
// C# program for the
// above approach
using System;
class GFG{
// Function to find total number of
// possible arrangements of array
static int waysForPairwiseSumToBeK(int i, int rem,
int previous,
int N, int [,,]dp)
{
// Base Case
if (i == N)
{
if (rem == 0)
return 1;
else
return 0;
}
// If rem exceeds
// 'k' return 0
if (rem < 0)
return 0;
// Return the already
// calculated states
if (dp[i, rem, previous] != -1)
return dp[i, rem, previous];
int ways = 0;
// Place a '0' at current position
ways += waysForPairwiseSumToBeK(i + 1, rem,
0, N, dp);
// Place a '1' at current position
// Add it to previous value
ways += waysForPairwiseSumToBeK(i + 1, rem -
(previous),
1, N, dp);
// Place a '2' at current position.
// Add it to previous value.
ways += waysForPairwiseSumToBeK(i + 1, rem -
(2 * previous),
2, N, dp);
// Store the current state result
// return the same result
dp[i, rem, previous] = ways;
return ways;
}
// Function to find number of possible
// arrangements of array with 0, 1, and
// 2 having pairwise product sum K
static void countOfArrays(int i, int rem,
int previous, int N)
{
// Store the overlapping states
int [,,]dp = new int[ 15, 15, 3 ];
// Initialize dp table with -1
for(int p = 0; p < 15; p++)
{
for(int q = 0; q < 15; q++)
{
for(int r = 0; r < 3; r++)
dp[p, q, r] = -1;
}
}
// Stores total number of ways
int totWays = waysForPairwiseSumToBeK(i, rem,
previous,
N, dp);
// Print number of ways
Console.Write(totWays);
}
// Driver Code
public static void Main(String []args)
{
// Given N and K
int N = 4, K = 3;
// Function Call
countOfArrays(0, K, 0, N);
}
}
// This code is contributed by gauravrajput1
Javascript
5
时间复杂度: O(N*K)
辅助空间: O(N*K)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。