给定一个整数 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 N是N分裂的复合被加数的数量。
让我们为从 1 到 15 的所有数字找到一个答案。几个观察结果:
- 只有 4、6、9 出现在最佳分裂中。
- 多次使用 6 或 9 没有好处,因为 6 + 6 = 4 + 4 + 4, 9 + 9 = 6 + 6 + 6。
- 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 maximum 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 };
// initialize
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 maximum 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 maximum 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 maximum 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
?>
Javascript
输出:
3