给定整数n ,任务是找到总和等于N的最小立方体数。
例子:
Input: N = 496
Output: 3
43 + 63 + 63 = 496
Note that 13 + 33 + 53 + 73 = 496 but it requires 4 cubes.
Input: N = 15
Output: 8
天真的方法:编写一种递归方法,将每个小于N个说X的理想立方体作为求和的一部分,然后递归得出剩余总和N – X所需的立方体数。该解决方案的时间复杂度是指数级的。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// Function to return the minimum
// number of cubes whose sum is k
int MinOfCubed(int k)
{
// If k is less than the 2^3
if (k < 8)
return k;
// Initialize with the maximum
// number of cubes required
int res = k;
for (int i = 1; i <= k; i++) {
if ((i * i * i) > k)
return res;
res = min(res, MinOfCubed(k - (i * i * i)) + 1);
}
return res;
}
// Driver code
int main()
{
int num = 15;
cout << MinOfCubed(num);
return 0;
}
Java
// Java implementation of the approach
class GFG {
// Function to return the minimum
// number of cubes whose sum is k
static int MinOfCubed(int k)
{
// If k is less than the 2^3
if (k < 8)
return k;
// Initialize with the maximum
// number of cubes required
int res = k;
for (int i = 1; i <= k; i++) {
if ((i * i * i) > k)
return res;
res = Math.min(res, MinOfCubed(k - (i * i * i)) + 1);
}
return res;
}
// Driver code
public static void main(String[] args)
{
int num = 15;
System.out.println(MinOfCubed(num));
}
}
// This code has been contributed by 29AjayKumar
Python3
# Python3 implementation of the approach
# Function to return the minimum
# number of cubes whose sum is k
def MinOfCubed(k):
# If k is less than the 2 ^ 3
if (k < 8):
return k;
# Initialize with the maximum
# number of cubes required
res = k;
for i in range(1, k + 1):
if ((i * i * i) > k):
return res;
res = min(res, MinOfCubed(k - (i * i * i)) + 1);
return res;
# Driver code
num = 15;
print(MinOfCubed(num));
# This code contributed by PrinciRaj1992
C#
// C# implementation of the approach
using System;
class GFG {
// Function to return the minimum
// number of cubes whose sum is k
static int MinOfCubed(int k)
{
// If k is less than the 2^3
if (k < 8)
return k;
// Initialize with the maximum
// number of cubes required
int res = k;
for (int i = 1; i <= k; i++) {
if ((i * i * i) > k)
return res;
res = Math.Min(res, MinOfCubed(k - (i * i * i)) + 1);
}
return res;
}
// Driver code
static public void Main()
{
int num = 15;
Console.WriteLine(MinOfCubed(num));
}
}
// This code has been contributed by ajit.
PHP
$k)
return $res;
$res = min($res, MinOfCubed($k - ($i *$i * $i)) + 1);
}
return $res;
}
// Driver code
$num = 15;
echo MinOfCubed($num);
// This code is contributed by Ryuga
?>
C++
// C++ implementation of the approach
#include
using namespace std;
// Function to return the minimum
// number of cubes whose sum is k
int MinOfCubedDP(int k)
{
int *DP = new int[k + 1], j = 1, t = 1;
DP[0] = 0;
for (int i = 1; i <= k; i++) {
DP[i] = INT_MAX;
// While current perfect cube
// is less than current element
while (j <= i) {
// If i is a perfect cube
if (j == i)
DP[i] = 1;
// i = (i - 1) + 1^3
else if (DP[i] > DP[i - j])
DP[i] = DP[i - j] + 1;
// Next perfect cube
t++;
j = t * t * t;
}
// Re-initialization for next element
t = j = 1;
}
return DP[k];
}
// Driver code
int main()
{
int num = 15;
cout << MinOfCubedDP(num);
return 0;
}
Java
// Java implementation of the approach
class GFG {
// Function to return the minimum
// number of cubes whose sum is k
static int MinOfCubedDP(int k)
{
int[] DP = new int[k + 1];
int j = 1, t = 1;
DP[0] = 0;
for (int i = 1; i <= k; i++) {
DP[i] = Integer.MAX_VALUE;
// While current perfect cube
// is less than current element
while (j <= i) {
// If i is a perfect cube
if (j == i)
DP[i] = 1;
// i = (i - 1) + 1^3
else if (DP[i] > DP[i - j])
DP[i] = DP[i - j] + 1;
// Next perfect cube
t++;
j = t * t * t;
}
// Re-initialization for next element
t = j = 1;
}
return DP[k];
}
// Driver code
public static void main(String[] args)
{
int num = 15;
System.out.println(MinOfCubedDP(num));
}
}
/* This code contributed by PrinciRaj1992 */
Python3
# Python implementation of the approach
import sys
# Function to return the minimum
# number of cubes whose sum is k
def MinOfCubedDP(k):
DP = [0] * (k + 1);
j = 1;
t = 1;
DP[0] = 0;
for i in range(1, k + 1):
DP[i] = sys.maxsize;
# While current perfect cube
# is less than current element
while (j <= i):
# If i is a perfect cube
if (j == i):
DP[i] = 1;
# i = (i - 1) + 1^3
elif (DP[i] > DP[i - j]):
DP[i] = DP[i - j] + 1;
# Next perfect cube
t += 1;
j = t * t * t;
# Re-initialization for next element
t = j = 1;
return DP[k];
# Driver code
num = 15;
print(MinOfCubedDP(num));
# This code contributed by Rajput-Ji
C#
// C# implementation of the approach
using System;
class GFG {
// Function to return the minimum
// number of cubes whose sum is k
static int MinOfCubedDP(int k)
{
int[] DP = new int[k + 1];
int j = 1, t = 1;
DP[0] = 0;
for (int i = 1; i <= k; i++) {
DP[i] = int.MaxValue;
// While current perfect cube
// is less than current element
while (j <= i) {
// If i is a perfect cube
if (j == i)
DP[i] = 1;
// i = (i - 1) + 1^3
else if (DP[i] > DP[i - j])
DP[i] = DP[i - j] + 1;
// Next perfect cube
t++;
j = t * t * t;
}
// Re-initialization for next element
t = j = 1;
}
return DP[k];
}
// Driver code
public static void Main()
{
int num = 15;
Console.WriteLine(MinOfCubedDP(num));
}
}
/* This code contributed by Code_Mech */
PHP
$DP[$i - $j])
$DP[$i] = $DP[$i - $j] + 1;
// Next perfect cube
$t++;
$j = $t * $t * $t;
}
// Re-initialization for next element
$t = $j = 1;
}
return $DP[$k];
}
// Driver code
$num = 15;
echo(MinOfCubedDP($num));
// This code contributed by Code_Mech
?>
输出:
8
高效方法:如果为上述解决方案绘制完整的递归树,则可以看到许多子问题一次又一次地得到解决,因此我们可以看到此问题具有重叠的子问题属性。这导致我们使用动态编程范例解决问题。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// Function to return the minimum
// number of cubes whose sum is k
int MinOfCubedDP(int k)
{
int *DP = new int[k + 1], j = 1, t = 1;
DP[0] = 0;
for (int i = 1; i <= k; i++) {
DP[i] = INT_MAX;
// While current perfect cube
// is less than current element
while (j <= i) {
// If i is a perfect cube
if (j == i)
DP[i] = 1;
// i = (i - 1) + 1^3
else if (DP[i] > DP[i - j])
DP[i] = DP[i - j] + 1;
// Next perfect cube
t++;
j = t * t * t;
}
// Re-initialization for next element
t = j = 1;
}
return DP[k];
}
// Driver code
int main()
{
int num = 15;
cout << MinOfCubedDP(num);
return 0;
}
Java
// Java implementation of the approach
class GFG {
// Function to return the minimum
// number of cubes whose sum is k
static int MinOfCubedDP(int k)
{
int[] DP = new int[k + 1];
int j = 1, t = 1;
DP[0] = 0;
for (int i = 1; i <= k; i++) {
DP[i] = Integer.MAX_VALUE;
// While current perfect cube
// is less than current element
while (j <= i) {
// If i is a perfect cube
if (j == i)
DP[i] = 1;
// i = (i - 1) + 1^3
else if (DP[i] > DP[i - j])
DP[i] = DP[i - j] + 1;
// Next perfect cube
t++;
j = t * t * t;
}
// Re-initialization for next element
t = j = 1;
}
return DP[k];
}
// Driver code
public static void main(String[] args)
{
int num = 15;
System.out.println(MinOfCubedDP(num));
}
}
/* This code contributed by PrinciRaj1992 */
Python3
# Python implementation of the approach
import sys
# Function to return the minimum
# number of cubes whose sum is k
def MinOfCubedDP(k):
DP = [0] * (k + 1);
j = 1;
t = 1;
DP[0] = 0;
for i in range(1, k + 1):
DP[i] = sys.maxsize;
# While current perfect cube
# is less than current element
while (j <= i):
# If i is a perfect cube
if (j == i):
DP[i] = 1;
# i = (i - 1) + 1^3
elif (DP[i] > DP[i - j]):
DP[i] = DP[i - j] + 1;
# Next perfect cube
t += 1;
j = t * t * t;
# Re-initialization for next element
t = j = 1;
return DP[k];
# Driver code
num = 15;
print(MinOfCubedDP(num));
# This code contributed by Rajput-Ji
C#
// C# implementation of the approach
using System;
class GFG {
// Function to return the minimum
// number of cubes whose sum is k
static int MinOfCubedDP(int k)
{
int[] DP = new int[k + 1];
int j = 1, t = 1;
DP[0] = 0;
for (int i = 1; i <= k; i++) {
DP[i] = int.MaxValue;
// While current perfect cube
// is less than current element
while (j <= i) {
// If i is a perfect cube
if (j == i)
DP[i] = 1;
// i = (i - 1) + 1^3
else if (DP[i] > DP[i - j])
DP[i] = DP[i - j] + 1;
// Next perfect cube
t++;
j = t * t * t;
}
// Re-initialization for next element
t = j = 1;
}
return DP[k];
}
// Driver code
public static void Main()
{
int num = 15;
Console.WriteLine(MinOfCubedDP(num));
}
}
/* This code contributed by Code_Mech */
的PHP
$DP[$i - $j])
$DP[$i] = $DP[$i - $j] + 1;
// Next perfect cube
$t++;
$j = $t * $t * $t;
}
// Re-initialization for next element
$t = $j = 1;
}
return $DP[$k];
}
// Driver code
$num = 15;
echo(MinOfCubedDP($num));
// This code contributed by Code_Mech
?>
输出:
8
乍看之下,该算法似乎可以在多项式时间内工作,因为我们有两个嵌套循环,外层循环为O(n),内层循环为O(n ^(1/3))。因此整个算法取O(n * n ^(1/3))。但是,复杂度是输入长度的函数吗?为了表示大小为n的数字,我们需要m = log(n)–(以2为底的对数)位。在这种情况下,n = 2 ^ m。如果在公式O(n * n ^(1/3))中将2 ^ m设置为n,则会看到时间复杂度仍然是指数级的。该算法称为伪多项式。