📜  找出一个数字的复合求和的最大数量

📅  最后修改于: 2021-05-04 22:30:00             🧑  作者: Mango

给定整数N(1 <= N <= 10 ^ 9)。任务是将N表示为组合求和的最大可能数目的总和,并打印此最大数目,如果没有此类拆分,则打印-1。可以有多个查询

例子:

Input : 12
Output : 3
Explanation : 12 can be written has 4 + 4 + 4 or 6 + 6 or 8 + 4
But, 4 + 4 + 4 has maximum number of summands.

Input : 7
Output : -1

方法:请注意,最小复合数等于4。因此,在大数的拆分中将有很多4是很合逻辑的。让我们写一个小数(1 <= M <= N)dp NN分裂中复合求和数。

让我们找到从1到15的所有数字的答案。

  1. 最佳分割中仅出现4、6、9。
  2. 多次使用6或9无益,因为6 + 6 = 4 + 4 + 4、9 + 9 = 6 + 6 + 6。
  3. 12、13、14、15具有有效的分割。

让我们证明所有大于15的数字在最佳分割中将有4个。让我们猜测这是不正确的。如果拆分的最小数目既不是4,也不是6也不是9,则该数目将通过归纳法进行一些非平凡的拆分。

如果此数字为6或9,并且我们将通过该数字减少查询,那么我们迟早会得到一些较小的数字(小于或等于15)。没有小数的拆分,或者拆分中包含4(并且与第一个数字的最小值相矛盾),或者包含6和9。因此,在所有情况下我们都存在矛盾。

我们可以从任何大查询中减去4,我们的解决方案是正确的。

如果我们的查询n是小数字,让我们打印dp n 。否则,我们找到最小数k,使得n – 4·k是一个小数。然后打印k + dp n – 4·k。

下面是上述方法的实现:

C++
// C++ implementation of the above approach
  
#include 
using namespace std;
  
const int maxn = 16;
  
// Function to generate the dp array
vector precompute()
{
    vector dp(maxn, -1);
    dp[0] = 0;
  
    for (int i = 1; i < maxn; ++i) {
  
        // combination of three integers
        for (auto j : vector{ 4, 6, 9 }) {
  
            // take the maxium number of summands
            if (i >= j && dp[i - j] != -1) {
                dp[i] = max(dp[i], dp[i - j] + 1);
            }
        }
    }
  
    return dp;
}
  
// Function to find the maximum number of summands
int Maximum_Summands(vector dp, int n)
{
    // If n is a smaller number, less than 16
    // return dp[n]
    if (n < maxn)
        return dp[n];
  
    else {
  
        // Else, find a minimal number t
        // as explained in solution
        int t = (n - maxn) / 4 + 1;
        return t + dp[n - 4 * t];
    }
}
  
// Driver code
int main()
{
    int n = 12;
  
    // Generate dp array
    vector dp = precompute();
  
    cout << Maximum_Summands(dp, n) << endl;
  
    return 0;
}


Java
// Java implementation of the above approach 
class GFG
{
  
static int maxn = 16; 
  
// Function to generate the dp array 
static int[] precompute() 
{ 
int dp[] = new int[maxn], arr[]={ 4, 6, 9 };
  
// initilize
for(int i = 0; i < maxn; i++)dp[i] = -1;
  
dp[0] = 0; 
  
for (int i = 1; i < maxn; ++i) 
{ 
  
    // combination of three integers 
    for (int k = 0; k < 3; k++) 
    {
        int j = arr[k];
  
        // take the maxium number of summands 
        if (i >= j && dp[i - j] != -1) 
        { 
            dp[i] = Math.max(dp[i], dp[i - j] + 1); 
        } 
    } 
} 
  
return dp; 
} 
  
// Function to find the maximum number of summands 
static int Maximum_Summands(int[] dp, int n) 
{ 
// If n is a smaller number, less than 16 
// return dp[n] 
if (n < maxn) 
    return dp[n]; 
  
else { 
  
    // Else, find a minimal number t 
    // as explained in solution 
    int t = (n - maxn) / 4 + 1; 
    return t + dp[n - 4 * t]; 
} 
} 
  
// Driver code 
public static void main(String args[]) 
{ 
    int n = 12; 
  
    // Generate dp array 
    int[] dp = precompute(); 
  
    System.out.println(Maximum_Summands(dp, n)); 
}
} 
  
// This code is contributed by Arnab Kundu


Python3
# Python 3 implementation of the above approach
global maxn
maxn = 16
  
# Function to generate the dp array
def precompute():
    dp = [-1 for i in range(maxn)]
    dp[0] = 0
  
    v = [4, 6, 9]
  
    for i in range(1, maxn, 1):
          
        # combination of three integers
        for k in range(3):
            j = v[k]
              
            # take the maxium number of summands
            if (i >= j and dp[i - j] != -1):
                dp[i] = max(dp[i], dp[i - j] + 1)
  
    return dp
  
# Function to find the maximum number of summands
def Maximum_Summands(dp, n):
      
    # If n is a smaller number, 
    # less than 16, return dp[n]
    if (n < maxn):
        return dp[n]
  
    else:
          
        # Else, find a minimal number t
        # as explained in solution
        t = int((n - maxn) / 4)+ 1
        return t + dp[n - 4 * t]
  
# Driver code
if __name__ == '__main__':
    n = 12
  
    # Generate dp array
    dp = precompute()
  
    print(Maximum_Summands(dp, n))
      
# This code is contributed by
# Surendra_Gangwar


C#
// C# implementation of the above approach
using System;
using System.Collections;
  
class GFG
{
      
static int maxn = 16;
static int[] dp = new int[maxn + 1];
  
// Function to generate the dp array
static void precompute()
{
    for(int i = 0; i <= maxn; i++)
    dp[i] = -1;
    dp[0] = 0;
    int[] vec = { 4, 6, 9 };
    for (int i = 1; i < maxn; ++i) 
    {
  
        // combination of three integers
        foreach (int j in vec)
        {
  
            // take the maxium number of summands
            if (i >= j && dp[i - j] != -1) 
            {
                dp[i] = Math.Max(dp[i], dp[i - j] + 1);
            }
        }
    }
  
}
  
// Function to find the maximum number of summands
static int Maximum_Summands(int n)
{
    // If n is a smaller number, less than 16
    // return dp[n]
    if (n < maxn)
        return dp[n];
  
    else 
    {
  
        // Else, find a minimal number t
        // as explained in solution
        int t = (n - maxn) / 4 + 1;
        return t + dp[n - 4 * t];
    }
}
  
// Driver code
static void Main()
{
    int n = 12;
  
    // Generate dp array
    precompute();
  
    Console.WriteLine(Maximum_Summands(n));
}
}
  
// This code is contributed by chandan_jnu


PHP
= $j && $dp[$i - $j] != -1) 
            { 
                $dp[$i] = max($dp[$i], 
                              $dp[$i - $j] + 1); 
            } 
        } 
    } 
  
    return $dp; 
} 
  
// Function to find the maximum 
// number of summands 
function Maximum_Summands($dp, $n) 
{ 
    // If n is a smaller number, 
    // less than 16 return dp[n] 
    if ($n < $GLOBALS['maxn']) 
        return $dp[$n]; 
  
    else
    { 
  
        // Else, find a minimal number t 
        // as explained in solution 
        $t = ($n - $GLOBALS['maxn']) / 4 + 1; 
        return $t + $dp[$n - 4 * $t]; 
    } 
} 
  
// Driver code 
$n = 12; 
  
// Generate dp array 
$dp = precompute(); 
  
echo Maximum_Summands($dp, $n); 
  
// This code is contributed by Ryuga
?>


输出:
3