📌  相关文章
📜  长度为 K 的子序列 X 使得 gcd(X[0], X[1]) + (X[2], X[3]) + … 最大化

📅  最后修改于: 2021-09-17 06:52:21             🧑  作者: Mango

给定一个大小为N的数组a 。任务是找到一个长度为K的子序列X ,使得gcd(X[0], X[1]) + (X[2], X[3]) + …是最大值。
K是偶数。
例子:

朴素的方法:朴素的方法是使用递归生成所有长度为 K 的子序列并找到可能的最大值。
高效的方法: 一种有效的方法是使用动态规划来解决上述问题。如果将第 i 个索引元素作为第j 个元素,则让dp[i][j]表示对 gcd sum 的值。递归生成所有可能的子序列。如果所取元素的cnt奇数,则将gcd (a[prev], a[current]) 添加到总和中,因为该数字将是该对中的第二个,并为下一个元素重复出现。如果cnteven ,则只需重复设置a[i]作为前一个元素。记忆已被用于避免重新计算相同的重复。所有生成的总和的最大值将是答案。
下面是上述方法的实现:

C++
// C++ program to find the sum of
// the addition of all possible subsets
#include 
using namespace std;
const int MAX = 100;
 
// Recursive function to find the maximum value of
// the given recurrence
int recur(int ind, int cnt, int last, int a[],
          int n, int k, int dp[][MAX])
{
 
    // If we get K elements
    if (cnt == k)
        return 0;
 
    // If we have reached the end
    // and K elements are not there
    if (ind == n)
        return -1e9;
 
    // If the state has been visited
    if (dp[ind][cnt] != -1)
        return dp[ind][cnt];
    int ans = 0;
 
    // Iterate for every element as the
    // next possible element
    // and take the element which gives
    // the maximum answer
    for (int i = ind; i < n; i++)
    {
        // If this element is the first element
        // in the individual pair in the subsequence
        // then simply recurrence with the last
        // element as i-th index
        if (cnt % 2 == 0)
         ans=max(ans,recur(i + 1, cnt + 1, i, a, n, k, dp));
 
        // If this element is the second element in
        // the individual pair, the find gcd with
        // the previous element and add to the answer
        // and recur for the next element
        else
            ans = max(ans, __gcd(a[last], a[i]) +
                recur(i + 1, cnt + 1, 0, a, n, k, dp));
    }
 
    return dp[ind][cnt] = ans;
}
 
// Driver Code
int main()
{
    int a[] = { 4, 5, 3, 7, 8, 10, 9, 8 };
    int n = sizeof(a) / sizeof(a[0]);
    int k = 4;
    int dp[n][MAX];
    memset(dp, -1, sizeof dp);
 
    cout << recur(0, 0, 0, a, n, k, dp);
}


Java
// Java program to find the sum of
// the addition of all possible subsets
import java.util.*;
 
class GFG
{
 
static int MAX = 100;
 
// Recursive function to find the maximum value of
// the given recurrence
static int recur(int ind, int cnt, int last, int a[],
                            int n, int k, int dp[][])
{
 
    // If we get K elements
    if (cnt == k)
        return 0;
 
    // If we have reached the end
    // and K elements are not there
    if (ind == n)
        return (int) -1e9;
 
    // If the state has been visited
    if (dp[ind][cnt] != -1)
        return dp[ind][cnt];
    int ans = 0;
 
    // Iterate for every element as the
    // next possible element
    // and take the element which gives
    // the maximum answer
    for (int i = ind; i < n; i++)
    {
        // If this element is the first element
        // in the individual pair in the subsequence
        // then simply recurrence with the last
        // element as i-th index
        if (cnt % 2 == 0)
            ans = Math.max(ans,recur(i + 1, cnt + 1, i, a, n, k, dp));
 
        // If this element is the second element in
        // the individual pair, the find gcd with
        // the previous element and add to the answer
        // and recur for the next element
        else
            ans = Math.max(ans, __gcd(a[last], a[i]) +
                recur(i + 1, cnt + 1, 0, a, n, k, dp));
    }
 
    return dp[ind][cnt] = ans;
}
 
static int __gcd(int a, int b)
{
    if (b == 0)
        return a;
    return __gcd(b, a % b);
     
}
 
// Driver Code
public static void main(String[] args)
{
    int a[] = { 4, 5, 3, 7, 8, 10, 9, 8 };
    int n = a.length;
    int k = 4;
    int [][]dp = new int[n][MAX];
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < MAX; j++)
        {
            dp[i][j] = -1;
        }
    }
    System.out.println(recur(0, 0, 0, a, n, k, dp));
    }
}
 
// This code is contributed by Rajput-Ji


Python3
# Python3 program to find the sum of
# the addition of all possible subsets
from math import gcd as __gcd
MAX = 100
 
# Recursive function to find the
# maximum value of the given recurrence
def recur(ind, cnt, last, a, n, k, dp):
 
    # If we get K elements
    if (cnt == k):
        return 0
 
    # If we have reached the end
    # and K elements are not there
    if (ind == n):
        return -10**9
 
    # If the state has been visited
    if (dp[ind][cnt] != -1):
        return dp[ind][cnt]
    ans = 0
 
    # Iterate for every element as the
    # next possible element
    # and take the element which gives
    # the maximum answer
    for i in range(ind, n):
         
        # If this element is the first element
        # in the individual pair in the subsequence
        # then simply recurrence with the last
        # element as i-th index
        if (cnt % 2 == 0):
            ans = max(ans, recur(i + 1, cnt + 1,
                                 i, a, n, k, dp))
 
        # If this element is the second element in
        # the individual pair, the find gcd with
        # the previous element and add to the answer
        # and recur for the next element
        else:
            ans = max(ans, __gcd(a[last], a[i]) +
                      recur(i + 1, cnt + 1, 0, a, n, k, dp))
 
    dp[ind][cnt] = ans
    return ans
 
# Driver Code
a = [4, 5, 3, 7, 8, 10, 9, 8 ]
 
n = len(a)
k = 4;
dp = [[-1 for i in range(MAX)]
          for i in range(n)]
 
print(recur(0, 0, 0, a, n, k, dp))
 
# This code is contributed by Mohit Kumar


C#
// C# program to find the sum of
// the addition of all possible subsets
using System;
     
class GFG
{
 
static int MAX = 100;
 
// Recursive function to find the maximum value of
// the given recurrence
static int recur(int ind, int cnt, int last, int []a,
                            int n, int k, int [,]dp)
{
 
    // If we get K elements
    if (cnt == k)
        return 0;
 
    // If we have reached the end
    // and K elements are not there
    if (ind == n)
        return (int) -1e9;
 
    // If the state has been visited
    if (dp[ind,cnt] != -1)
        return dp[ind,cnt];
    int ans = 0;
 
    // Iterate for every element as the
    // next possible element
    // and take the element which gives
    // the maximum answer
    for (int i = ind; i < n; i++)
    {
        // If this element is the first element
        // in the individual pair in the subsequence
        // then simply recurrence with the last
        // element as i-th index
        if (cnt % 2 == 0)
            ans = Math.Max(ans,recur(i + 1, cnt + 1, i, a, n, k, dp));
 
        // If this element is the second element in
        // the individual pair, the find gcd with
        // the previous element and add to the answer
        // and recur for the next element
        else
            ans = Math.Max(ans, __gcd(a[last], a[i]) +
                recur(i + 1, cnt + 1, 0, a, n, k, dp));
    }
 
    return dp[ind,cnt] = ans;
}
 
static int __gcd(int a, int b)
{
    if (b == 0)
        return a;
    return __gcd(b, a % b);
     
}
 
// Driver Code
public static void Main(String[] args)
{
    int []a = { 4, 5, 3, 7, 8, 10, 9, 8 };
    int n = a.Length;
    int k = 4;
    int [,]dp = new int[n,MAX];
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < MAX; j++)
        {
            dp[i,j] = -1;
        }
    }
    Console.WriteLine(recur(0, 0, 0, a, n, k, dp));
}
}
 
// This code is contributed by Princi Singh


Javascript


输出:
9

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程