给定一个整数数组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]
The sum of digits = 2, 2, 18 and 7 respectively.
So the product of digit sums in pairs = 2 * 1 + 18 * 7 = 2 + 126 = 128, which is the 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]
The sum of digits = 1, 5, 9, 6, 2 and 5 respectively.
So the product of digit sums in pairs = 1 * 5 + 9 * 6 + 2 * 5 = 5 + 54 + 10 = 69, which is the maximum.
方法:想法是使用动态规划。因为我们需要通过包含或排除数组中的某些元素来在数组中找到对以形成子序列。所以让DP[i][j][k]是我们的dp 数组,它存储元素的数字总和的最大乘积,直到索引i长度为j ,最后一个元素为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
Javascript
69
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。