给定两个整数N和K,任务是找到可以通过使用值0,1被产生的N -length阵列的数量,以及2任意次数,使得所述阵列的所有相邻的成对的乘积之和是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 table中存储的结果。
- 在上述递归调用结束后,通过函数打印出具有相邻的成对乘积为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
输出:
5
时间复杂度: O(N * K)
辅助空间: O(N * K)