给定整数N,任务是找到由F(N)= max(N,F(N / 2)+ F(N / 3)+ F(N / 4)给出的函数F(n)的最大值) 。
例子:
Input: N = 3
Output: 3
Explanation:
F(3) = max(3, F(1) + F(1) + F(0)) as F(0) = 0 and F(1) = 1
F(3) = max(3, 1 + 1+ 0)
F(3) = max(3, 2)
Hence, the maximum value of F(3) is 3.
Input: N = 12
Output:13
Explanation:
F(12) = max(12, F(6) + F(4) + F(3))
F(6) = max(6, F(3) + F(2) + F(1))
F(3) = max(3, F(1) + F(1) + F(0)) as F(0) = 0 and F(1) = 1
F(3) = max(3, 1 + 1+ 0)
F(3) = max(3, 2) = 3
F(2) = max(2, F(1) + F(0) + F(0))
F(2) = max(2,1 + 0 + 0) = 2
F(4) = max(4, F(2) + F(1) + F(1))
F(4) = max(4, 2 + 1 + 1) = 4
F(6) = max(6, 3 + 2 + 1) = 6
Now, F(12) = max(12, 6 + 4 + 3)
F(12) = max(12, 13)
Hence, the maximum value of F(12) is 13.
天真的方法:最简单的方法是使用递归来计算F(N)的值。在每个步骤中,分别对值N / 2 , N / 3和N / 4调用三个递归调用,然后每个递归调用返回N的最大值和这些递归调用返回的值之和。在所有递归调用结束后,将值打印为结果。
时间复杂度: O(3 N )
辅助空间: O(1)
使用自下而上方法的动态编程:也可以使用辅助数组dp []减少上述递归调用,并以自下而上的方法计算每个状态的值。步骤如下:
- 创建大小为N的辅助数组dp [] 。
- 将状态0和1初始化为dp [0] = 0和dp [1] = 1 。
- 在[2,N]范围内遍历数组dp [ ]并将每个状态更新为:
dp[i] = max(i, dp[i/2] + dp[i/3] + dp[i/4])
- 在上述步骤之后,打印dp [N]的值作为结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to build the auxiliary DP
// array from the start
void build(int dp[], int N)
{
// Base Case
dp[0] = 0;
dp[1] = 1;
// Iterate over the range
for (int i = 2; i <= N; i++) {
// Update each state
dp[i] = max(i, dp[i / 2]
+ dp[i / 3]
+ dp[i / 4]);
}
}
// Function to find the maximum value of
// F(n) = max(n, F[n/2] + F[n/3] + F[n/4])
int maxValue(int N)
{
// Auxuliary DP array
int dp[N + 1];
// Function call to build DP array
build(dp, N);
// Print the answer
cout << dp[N];
}
// Driver Code
int main()
{
// Given N
int N = 12;
// Function Call
maxValue(N);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to build the auxiliary DP
// array from the start
static void build(int dp[], int N)
{
// Base Case
dp[0] = 0;
dp[1] = 1;
// Iterate over the range
for(int i = 2; i <= N; i++)
{
// Update each state
dp[i] = Math.max(i, dp[i / 2] +
dp[i / 3] +
dp[i / 4]);
}
}
// Function to find the maximum value of
// F(n) = max(n, F[n/2] + F[n/3] + F[n/4])
static void maxValue(int N)
{
// Auxuliary DP array
int dp[] = new int[N + 1];
// Function call to build DP array
build(dp, N);
// Print the answer
System.out.println(dp[N]);
}
// Driver code
public static void main(String[] args)
{
// Given N
int N = 12;
// Function Call
maxValue(N);
}
}
// This code is contributed by code_hunt
Python3
# Python3 program for the above approach
# Function to build the auxiliary DP
# array from the start
def build(dp, N):
# Base Case
dp[0] = 0
dp[1] = 1
# Iterate over the range
for i in range(2, N + 1):
# Update each state
dp[i] = max(i, dp[i // 2] +
dp[i // 3] +
dp[i // 4])
# Function to find the maximum value of
# F(n) = max(n, F[n/2] + F[n/3] + F[n/4])
def maxValue(N):
# Auxuliary DP array
dp = [0] * (N + 1)
# Function call to build DP array
build(dp, N)
# Print the answer
print(dp[N], end = "")
# Driver Code
if __name__ == '__main__':
# Given N
N = 12
# Function Call
maxValue(N)
# This code is contributed by mohit kumar 29
C#
// C# program for the
// above approach
using System;
class GFG{
// Function to build the
// auxiliary DP array
// from the start
static void build(int []dp,
int N)
{
// Base Case
dp[0] = 0;
dp[1] = 1;
// Iterate over the range
for(int i = 2; i <= N; i++)
{
// Update each state
dp[i] = Math.Max(i, dp[i / 2] +
dp[i / 3] +
dp[i / 4]);
}
}
// Function to find the
// maximum value of F(n) =
// max(n, F[n/2] + F[n/3] + F[n/4])
static void maxValue(int N)
{
// Auxuliary DP array
int []dp = new int[N + 1];
// Function call to
// build DP array
build(dp, N);
// Print the answer
Console.WriteLine(dp[N]);
}
// Driver code
public static void Main(String[] args)
{
// Given N
int N = 12;
// Function Call
maxValue(N);
}
}
// This code is contributed by Rajput-Ji
C++
// C++ program for the above approach
#include
using namespace std;
// Map used for memoization
map mp;
// Function to find maximum value
// of the given recurrence relation
int maxValue(int N)
{
// Base Case
if (N <= 1)
return N;
// If previously computed
if (mp[N] != 0)
return mp[N];
// Computing value of function
// when its not already computed
int ans = max(N, maxValue(N / 2)
+ maxValue(N / 3)
+ maxValue(N / 4));
// Storing value for further
// computation reduction
mp[N] = ans;
return ans;
}
// Utility function to find maximum value
// of the given recurrence relation
void maxValueUtil(int N)
{
// Stores final result
int result = maxValue(N);
// Print the result
cout << result;
}
// Drive Code
int main()
{
// Given N
int N = 12;
// Function Call
maxValueUtil(N);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
import java.lang.*;
class GFG{
// Map used for memoization
static Map mp = new HashMap<>();
// Function to find maximum value
// of the given recurrence relation
static int maxValue(int N)
{
// Base Case
if (N <= 1)
return N;
// If previously computed
if (mp.containsKey(N))
return mp.get(N);
// Computing value of function
// when its not already computed
int ans = Math.max(N, maxValue(N / 2) +
maxValue(N / 3) +
maxValue(N / 4));
// Storing value for further
// computation reduction
mp.put(N, ans);
return ans;
}
// Utility function to find maximum value
// of the given recurrence relation
static void maxValueUtil(int N)
{
// Stores final result
int result = maxValue(N);
// Print the result
System.out.print(result);
}
// Driver code
public static void main (String[] args)
{
// Given N
int N = 12;
// Function Call
maxValueUtil(N);
}
}
// This code is contributed by offbeat
Python3
# Python3 program for the above approach
# Map used for memoization
mp = {}
# Function to find maximum value
# of the given recurrence relation
def maxValue(N):
# Base Case
if (N <= 1):
return N
# If previously computed
if (N in mp):
return mp[N]
# Computing value of function
# when its not already computed
ans = (max(N, maxValue(N // 2) +
maxValue(N // 3) +
maxValue(N // 4)))
# Storing value for further
# computation reduction
if(N in mp):
mp[N] = ans
else:
mp[N] = mp.get(N, 0) + ans
return ans
# Utility function to find maximum value
# of the given recurrence relation
def maxValueUtil(N):
# Stores final result
result = maxValue(N)
# Print the result
print(result)
# Drive Code
if __name__ == '__main__':
# Given N
N = 12
# Function Call
maxValueUtil(N)
# This code is contributed by SURENDRA_GANGWAR
C#
// C# program for the
// above approach
using System;
using System.Collections.Generic;
class GFG{
// Map used for memoization
static Dictionary mp = new Dictionary();
// Function to find maximum value
// of the given recurrence relation
static int maxValue(int N)
{
// Base Case
if (N <= 1)
return N;
// If previously computed
if (mp.ContainsKey(N))
return mp[N];
// Computing value of function
// when its not already computed
int ans = Math.Max(N, maxValue(N / 2) +
maxValue(N / 3) +
maxValue(N / 4));
// Storing value for further
// computation reduction
mp.Add(N, ans);
return ans;
}
// Utility function to find
// maximum value of the given
// recurrence relation
static void maxValueUtil(int N)
{
// Stores readonly result
int result = maxValue(N);
// Print the result
Console.Write(result);
}
// Driver code
public static void Main(String[] args)
{
// Given N
int N = 12;
// Function Call
maxValueUtil(N);
}
}
// This code is contributed by Princi Singh
13
时间复杂度: O(N)
空间复杂度: O(N)
使用自顶向下方法的动态编程:与上述方法一样,每个递归调用都有很多重叠子问题。因此,为了优化上述方法,其思想是使用辅助空间映射来存储在每个递归调用中计算出的值并返回重复的存储状态。步骤如下:
- 初始化地图Map来存储在每个递归调用中计算的值。
- 基本情况:如果N的值为0或1,则结果分别为0和1 。同样,如果存在任何先前计算的状态,则将该值返回为:
>Base Case:
if(N <= 1) {
return N;
}
Memoized State:
if(Map.find(N) != Map.end()) {
return Map[N];
}
- 递归调用:如果不满足基本条件,则通过递归调用每个状态来找到当前状态的值,如下所示:
result = max(N, recursive_function(N/2) + recursive_function(N/3) + recursive_function(N/4))
- 返回语句:在每个递归调用中(基本情况除外),将在上一步中计算出的当前状态存储在映射中,并返回计算出的值作为当前状态的结果。
Map[N] = result;
return result;
- 完成上述步骤后,将值打印返回到所有递归调用的末尾。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Map used for memoization
map mp;
// Function to find maximum value
// of the given recurrence relation
int maxValue(int N)
{
// Base Case
if (N <= 1)
return N;
// If previously computed
if (mp[N] != 0)
return mp[N];
// Computing value of function
// when its not already computed
int ans = max(N, maxValue(N / 2)
+ maxValue(N / 3)
+ maxValue(N / 4));
// Storing value for further
// computation reduction
mp[N] = ans;
return ans;
}
// Utility function to find maximum value
// of the given recurrence relation
void maxValueUtil(int N)
{
// Stores final result
int result = maxValue(N);
// Print the result
cout << result;
}
// Drive Code
int main()
{
// Given N
int N = 12;
// Function Call
maxValueUtil(N);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
import java.lang.*;
class GFG{
// Map used for memoization
static Map mp = new HashMap<>();
// Function to find maximum value
// of the given recurrence relation
static int maxValue(int N)
{
// Base Case
if (N <= 1)
return N;
// If previously computed
if (mp.containsKey(N))
return mp.get(N);
// Computing value of function
// when its not already computed
int ans = Math.max(N, maxValue(N / 2) +
maxValue(N / 3) +
maxValue(N / 4));
// Storing value for further
// computation reduction
mp.put(N, ans);
return ans;
}
// Utility function to find maximum value
// of the given recurrence relation
static void maxValueUtil(int N)
{
// Stores final result
int result = maxValue(N);
// Print the result
System.out.print(result);
}
// Driver code
public static void main (String[] args)
{
// Given N
int N = 12;
// Function Call
maxValueUtil(N);
}
}
// This code is contributed by offbeat
Python3
# Python3 program for the above approach
# Map used for memoization
mp = {}
# Function to find maximum value
# of the given recurrence relation
def maxValue(N):
# Base Case
if (N <= 1):
return N
# If previously computed
if (N in mp):
return mp[N]
# Computing value of function
# when its not already computed
ans = (max(N, maxValue(N // 2) +
maxValue(N // 3) +
maxValue(N // 4)))
# Storing value for further
# computation reduction
if(N in mp):
mp[N] = ans
else:
mp[N] = mp.get(N, 0) + ans
return ans
# Utility function to find maximum value
# of the given recurrence relation
def maxValueUtil(N):
# Stores final result
result = maxValue(N)
# Print the result
print(result)
# Drive Code
if __name__ == '__main__':
# Given N
N = 12
# Function Call
maxValueUtil(N)
# This code is contributed by SURENDRA_GANGWAR
C#
// C# program for the
// above approach
using System;
using System.Collections.Generic;
class GFG{
// Map used for memoization
static Dictionary mp = new Dictionary();
// Function to find maximum value
// of the given recurrence relation
static int maxValue(int N)
{
// Base Case
if (N <= 1)
return N;
// If previously computed
if (mp.ContainsKey(N))
return mp[N];
// Computing value of function
// when its not already computed
int ans = Math.Max(N, maxValue(N / 2) +
maxValue(N / 3) +
maxValue(N / 4));
// Storing value for further
// computation reduction
mp.Add(N, ans);
return ans;
}
// Utility function to find
// maximum value of the given
// recurrence relation
static void maxValueUtil(int N)
{
// Stores readonly result
int result = maxValue(N);
// Print the result
Console.Write(result);
}
// Driver code
public static void Main(String[] args)
{
// Given N
int N = 12;
// Function Call
maxValueUtil(N);
}
}
// This code is contributed by Princi Singh
13
时间复杂度: O(log N)
辅助空间: O(log N)