给定一个整数数组arr [] ,任务是使长度为K的子序列中每个连续对的数字总和的乘积最大。
注意: K总是偶数,因为将在偶数长度上形成对。
例子:
Input: arr[] = {2, 100, 99, 3, 16}, K = 4
Output: 128
The optimal subsequence of length 4 is [2, 100, 99, 16]
Sum of digits = 2, 2, 18 and 7 respectively.
So Product of digit sums in pairs = 2 * 1 + 18 * 7 = 2 + 126 = 128, which is maximum.
Input: arr[] = {10, 5, 9, 101, 24, 2, 20, 14}, K = 6
Output: 69
The optimal subsequence of length 6 = [10, 5, 9, 24, 2, 14]
Sum of digits = 1, 5, 9, 6, 2 and 5 respectively.
So Product of digit sums in pairs = 1 * 5 + 9 * 6 + 2 * 5 = 5 + 54 + 10 = 69, which is maximum.
方法:想法是使用动态编程。由于我们需要通过在数组中包含或排除某些元素以形成子序列来在数组中查找对。因此,让DP [i] [j] [k]为我们的dp数组,该数组存储长度为j的索引i和最后一个元素为K的元素的位数之和的最大乘积。
观察结果:
- 奇数长度:在选择偶数长度子序列时,如果所选子序列的当前长度为奇数,则将选择最后一个元素的对。因此,我们必须计算最后一个元素与当前元素之和的乘积,然后在下一次调用中将偶数长度的last保持为0来递归。
- 偶数长度:在选择奇数长度子序列时,当所选子序列的当前长度为偶数时,我们只需要选择该对中的第一个元素即可。因此,我们仅选择当前元素作为下一个递归调用的最后一个元素,并在下一个递归调用中搜索该对的第二个元素。
- 排除元素:当前元素的另一个选项是排除当前元素,然后进一步选择元素。
下面是上述方法的实现:
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