📌  相关文章
📜  最大化长度为K的子序列中的连续对的数字总和的乘积

📅  最后修改于: 2021-05-14 02:15:30             🧑  作者: Mango

给定一个整数数组arr [] ,任务是使长度为K的子序列中每个连续对的数字总和的乘积最大

注意: K总是偶数,因为将在偶数长度上形成对。

例子:

方法:想法是使用动态编程。由于我们需要通过在数组中包含或排除某些元素以形成子序列来在数组中查找对。因此,让DP [i] [j] [k]为我们的dp数组,该数组存储长度为j的索引i和最后一个元素为K的元素的位数之和的最大乘积。

观察结果:

  • 奇数长度:在选择偶数长度子序列时,如果所选子序列的当前长度为奇数,则将选择最后一个元素的对。因此,我们必须计算最后一个元素与当前元素之和的乘积,然后在下一次调用中将偶数长度的last保持为0来递归。

    dp[i][j][k] = max(dp[i][j][k], productDigitSum(arr[k], arr[i]) + solve(i+1, j+1, 0))

  • 偶数长度:在选择奇数长度子序列时,当所选子序列的当前长度为偶数时,我们只需要选择该对中的第一个元素即可。因此,我们仅选择当前元素作为下一个递归调用的最后一个元素,并在下一个递归调用中搜索该对的第二个元素。

    dp[i][j][k] = max(dp[i][j][k], solve(i+1, j+1, i))

  • 排除元素:当前元素的另一个选项是排除当前元素,然后进一步选择元素。

    dp[i][j][k] = max(dp[i][j][k], solve(i+1, j, k))

下面是上述方法的实现:

C++
// C++ implementation to find the
// maximum product of the digit
// sum of the consecutive pairs of
// the subsequence of the length K
  
#include 
using namespace std;
  
const int MAX = 100;
int dp[1000][MAX][MAX];
  
// Function to find the product
// of two numbers digit sum
// in the pair
int productDigitSum(int x, int y)
{
    int sumx = 0;
  
    // Loop to find the digits of
    // the number
    while (x) {
        sumx += (x % 10);
        x /= 10;
    }
    int sumy = 0;
  
    // Loop to find the digits
    // of other number
    while (y) {
        sumy += (y % 10);
        y /= 10;
    }
    return (sumx * sumy);
}
  
// Function to find the subsequence
// of the length K
int solve(int arr[], int i, int len,
          int prev, int n, int k)
{
    // Base Case
    if (len == k)
        return 0;
  
    // Condition when we didn't reach
    // the length K, but ran out of
    // elements of the array
    if (i == n)
        return INT_MIN;
  
    // Condition if already calculated
    if (dp[i][len][prev])
        return dp[i][len][prev];
  
    int inc = 0, exc = 0;
  
    // If length upto this point is odd
    if (len & 1) {
  
        // If length is odd, it means we need
        // second element of this current pair,
        // calculate the product of digit sum of
        // current and previous element and recur
        // by moving towards next index
        inc = productDigitSum(arr[prev],
                              arr[i])
              + solve(arr, i + 1,
                      len + 1, 0, n, k);
    }
  
    // If length upto this point is even
    else {
        inc = solve(arr, i + 1, len + 1, i, n, k);
    }
  
    // Exclude this current element
    // and recur for next elements.
    exc = solve(arr, i + 1, len, prev, n, k);
  
    // return by memoizing it, by selecting
    // the maximum among two choices.
    return dp[i][len][prev] = max(inc, exc);
}
  
// Driver Code
int main()
{
    int arr[] = { 10, 5, 9, 101, 24, 2, 20, 14 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int k = 6;
    cout << solve(arr, 0, 0, 0, n, k);
}


Java
// Java implementation to find the
// maximum product of the digit
// sum of the consecutive pairs of
// the subsequence of the length K
import java.util.*;
  
class GFG{
      
static int MAX = 100;
static int dp[][][] = new int[1000][MAX][MAX];
  
// Function to find the product
// of two numbers digit sum
// in the pair
static int productDigitSum(int x, int y)
{
    int sumx = 0;
  
    // Loop to find the digits 
    // of the number
    while (x > 0) 
    {
        sumx += (x % 10);
        x /= 10;
    }
    int sumy = 0;
  
    // Loop to find the digits
    // of other number
    while (y > 0)
    {
        sumy += (y % 10);
        y /= 10;
    }
    return (sumx * sumy);
}
  
// Function to find the subsequence
// of the length K
static int solve(int arr[], int i, int len,
                  int prev, int n, int k)
{
      
    // Base Case
    if (len == k)
        return 0;
  
    // Condition when we didn't reach
    // the length K, but ran out of
    // elements of the array
    if (i == n)
        return Integer.MIN_VALUE;
  
    // Condition if already calculated
    if (dp[i][len][prev] != 0)
        return dp[i][len][prev];
  
    int inc = 0, exc = 0;
  
    // If length upto this point is odd
    if ((len & 1) != 0)
    {
  
        // If length is odd, it means we need
        // second element of this current pair,
        // calculate the product of digit sum of
        // current and previous element and recur
        // by moving towards next index
        inc = (productDigitSum(arr[prev], arr[i]) + 
               solve(arr, i + 1, len + 1, 0, n, k));
    }
  
    // If length upto this point is even
    else 
    {
        inc = solve(arr, i + 1, len + 1, i, n, k);
    }
  
    // Exclude this current element
    // and recur for next elements.
    exc = solve(arr, i + 1, len, prev, n, k);
  
    // Return by memoizing it, by selecting
    // the maximum among two choices.
    return dp[i][len][prev] = Math.max(inc, exc);
}
  
// Driver Code
public static void main(String []args)
{
    int arr[] = { 10, 5, 9, 101, 24, 2, 20, 14 };
    int n = arr.length;
    int k = 6;
      
    System.out.print(solve(arr, 0, 0, 0, n, k));
}
}
  
// This code is contributed by chitranayal


Python3
# Python3 implementation to find the 
# maximum product of the digit 
# sum of the consecutive pairs of 
# the subsequence of the length K 
import sys
  
MAX = 100
dp = []
  
for i in range(1000):
    temp1 = []
    for j in range(MAX):
        temp2 = []
          
        for k in range(MAX):
            temp2.append(0)
        temp1.append(temp2)
          
    dp.append(temp1)
  
# Function to find the product 
# of two numbers digit sum 
# in the pair 
def productDigitSum(x, y):
    sumx = 0
      
    # Loop to find the digits of 
    # the number
    while x:
        sumx += x % 10
        x = x // 10
          
    sumy = 0
      
    # Loop to find the digits 
    # of other number 
    while y:
        sumy += y % 10
        y = y // 10
      
    return sumx * sumy
  
# Function to find the subsequence 
# of the length K 
def solve(arr, i, len, prev, n, k):
      
    # Base case
    if len == k:
        return 0
      
    # Condition when we didn't reach 
    # the length K, but ran out of 
    # elements of the array 
    if i == n:
        return -sys.maxsize - 1
      
    # Condition if already calculated
    if dp[i][len][prev]:
        return dp[i][len][prev]
      
    # If length upto this point is odd
    if len & 1:
          
        # If length is odd, it means we need 
        # second element of this current pair, 
        # calculate the product of digit sum of 
        # current and previous element and recur 
        # by moving towards next index 
        inc = (productDigitSum(arr[prev], arr[i]) + 
               solve(arr, i + 1, len + 1, i, n, k))
    else:
          
        # If length upto this point is even
        inc = solve(arr, i + 1, len + 1, i, n, k)
      
    # Exclude this current element 
    # and recur for next elements. 
    exc = solve(arr, i + 1, len, prev, n, k)
      
    # Return by memoizing it, by selecting 
    # the maximum among two choices.
    dp[i][len][prev] = max(inc, exc)
    return dp[i][len][prev]
  
# Driver code
arr = [ 10, 5, 9, 101, 24, 2, 20, 14 ]
n = len(arr)
k = 6
print(solve(arr, 0, 0, 0, n, k))
  
# This code is contributed by Shivam Singh


C#
// C# implementation to find the
// maximum product of the digit
// sum of the consecutive pairs of
// the subsequence of the length K
using System;
class GFG{
      
static int MAX = 100;
static int [, ,]dp = new int[1000, MAX, MAX];
  
// Function to find the product
// of two numbers digit sum
// in the pair
static int productDigitSum(int x, int y)
{
    int sumx = 0;
  
    // Loop to find the digits 
    // of the number
    while (x > 0) 
    {
        sumx += (x % 10);
        x /= 10;
    }
    int sumy = 0;
  
    // Loop to find the digits
    // of other number
    while (y > 0)
    {
        sumy += (y % 10);
        y /= 10;
    }
    return (sumx * sumy);
}
  
// Function to find the subsequence
// of the length K
static int solve(int []arr, int i, int len,
                 int prev, int n, int k)
{
      
    // Base Case
    if (len == k)
        return 0;
  
    // Condition when we didn't reach
    // the length K, but ran out of
    // elements of the array
    if (i == n)
        return Int32.MinValue;
  
    // Condition if already calculated
    if (dp[i, len, prev] != 0)
        return dp[i, len, prev];
  
    int inc = 0, exc = 0;
  
    // If length upto this point is odd
    if ((len & 1) != 0)
    {
  
        // If length is odd, it means we need
        // second element of this current pair,
        // calculate the product of digit sum of
        // current and previous element and recur
        // by moving towards next index
        inc = (productDigitSum(arr[prev], arr[i]) + 
               solve(arr, i + 1, len + 1, 0, n, k));
    }
  
    // If length upto this point is even
    else
    {
        inc = solve(arr, i + 1, len + 1, i, n, k);
    }
  
    // Exclude this current element
    // and recur for next elements.
    exc = solve(arr, i + 1, len, prev, n, k);
  
    // Return by memoizing it, by selecting
    // the maximum among two choices.
    return dp[i, len, prev] = Math.Max(inc, exc);
}
  
// Driver Code
public static void Main()
{
    int []arr = { 10, 5, 9, 101, 24, 2, 20, 14 };
    int n = arr.Length;
    int k = 6;
      
    Console.Write(solve(arr, 0, 0, 0, n, k));
}
}
  
// This code is contributed by Nidhi_biet


输出:
69