📌  相关文章
📜  计算生成0、1、2的N长度数组的方式,以使所有相邻的成对乘积之和为K

📅  最后修改于: 2021-05-18 00:17:51             🧑  作者: Mango

给定两个整数NK,任务是找到可以通过使用值0,1被产生的N -length阵列的数量,以及2任意次数,使得所述阵列的所有相邻的成对的乘积之和是K。

例子:

简单方法:最简单的方法是,以产生其值可以是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表中。对于重叠,子问题使用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)