📜  备忘(1D,2D和3D)

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

大多数动态编程问题都可以通过两种方式解决:

  1. 列表:自下而上
  2. 备注:自上而下

解决DP中大多数问题的一种较容易的方法是,首先编写递归代码,然后再编写递归函数的自下而上的制表法或自上而下的记忆化。编写自顶向下方法的DP解决方案以解决任何问题的步骤是:

  1. 编写递归代码
  2. 记住返回值,并使用它减少递归调用。

一维记忆

第一步将是编写递归代码。在下面的程序中,显示了与递归相关的程序,其中只有一个参数会更改其值。由于只有一个参数是非恒定的,因此此方法称为一维备注。例如,在斐波那契级数中找到第N个项的斐波那契级数问题。递归方法已在此处进行了讨论。
下面给出的是找到第N个项的递归代码:

C++
// C++ program to find the Nth term
// of Fibonacci series
#include 
using namespace std;
 
// Fibonacci Series using Recursion
int fib(int n)
{
 
    // Base case
    if (n <= 1)
        return n;
 
    // recursive calls
    return fib(n - 1) + fib(n - 2);
}
 
// Driver Code
int main()
{
    int n = 6;
    printf("%d", fib(n));
    return 0;
}


Java
// Java program to find the
// Nth term of Fibonacci series
import java.io.*;
 
class GFG
{
     
// Fibonacci Series
// using Recursion
static int fib(int n)
{
 
    // Base case
    if (n <= 1)
        return n;
 
    // recursive calls
    return fib(n - 1) +
           fib(n - 2);
}
 
// Driver Code
public static void main (String[] args)
{
    int n = 6;
    System.out.println(fib(n));
}
}
 
// This code is contributed
// by ajit


Python3
# Python3 program to find the Nth term
# of Fibonacci series
 
# Fibonacci Series using Recursion
def fib(n):
 
 
    # Base case
    if (n <= 1):
        return n
 
    # recursive calls
    return fib(n - 1) + fib(n - 2)
 
# Driver Code
if __name__=='__main__':
    n = 6
    print (fib(n))
  
# This code is contributed by
# Shivi_Aggarwal


C#
// C# program to find
// the Nth term of
// Fibonacci series
using System;
 
class GFG
{
     
// Fibonacci Series
// using Recursion
static int fib(int n)
{
    // Base case
    if (n <= 1)
        return n;
 
    // recursive calls
    return fib(n - 1) +
           fib(n - 2);
}
// Driver Code
static public void Main ()
{
    int n = 6;
    Console.WriteLine(fib(n));
}
}
 
// This code is contributed
// by akt_mit


Javascript


PHP


C++
// CPP program to find the Nth term
// of Fibonacci series
#include 
using namespace std;
int term[1000];
// Fibonacci Series using memoized Recursion
int fib(int n)
{
    // base case
    if (n <= 1)
        return n;
 
    // if fib(n) has already been computed
    // we do not do further recursive calls
    // and hence reduce the number of repeated
    // work
    if (term[n] != 0)
        return term[n];
 
    else {
 
        // store the computed value of fib(n)
        // in an array term at index n to
        // so that it does not needs to be
        // precomputed again
        term[n] = fib(n - 1) + fib(n - 2);
 
        return term[n];
    }
}
 
// Driver Code
int main()
{
    int n = 6;
    printf("%d", fib(n));
    return 0;
}


Java
// Java program to find
// the Nth term of
// Fibonacci series
import java.io.*;
 
class GFG
{
 
static  int []term = new int [1000];
// Fibonacci Series using
// memoized Recursion
static int fib(int n)
{
    // base case
    if (n <= 1)
        return n;
 
    // if fib(n) has already
    // been computed we do not
    // do further recursive
    // calls and hence reduce
    // the number of repeated
    // work
    if (term[n] != 0)
        return term[n];
 
    else
    {
 
        // store the computed value
        // of fib(n) in an array
        // term at index n to so that
        // it does not needs to be
        // precomputed again
        term[n] = fib(n - 1) +
                  fib(n - 2);
 
        return term[n];
    }
}
 
// Driver Code
public static void main (String[] args)
{
    int n = 6;
    System.out.println(fib(n));
}
}
 
// This code is contributed by ajit


Python3
# Python program to find the Nth term
# of Fibonacci series
term = [0 for i in range(1000)]
 
# Fibonacci Series using memoized Recursion
def fib(n):
   
  # base case
  if n <= 1:
    return n
 
  # if fib(n) has already been computed
  # we do not do further recursive calls
  # and hence reduce the number of repeated
  # work
  if term[n] != 0:
    return term[n]
 
  else:
     
    # store the computed value of fib(n)
    # in an array term at index n to
    # so that it does not needs to be
    # precomputed again
    term[n] = fib(n - 1) + fib(n - 2)
    return term[n]
 
# Driver Code
n = 6
print(fib(n))
 
# This code is contributed by rohitsingh07052


C#
// C# program to find
// the Nth term of
// Fibonacci series
 
using System;
class GFG
{
      
// Fibonacci Series using
// memoized Recursion
static int fib(int n)
{
    int[] term = new int [1000];
      
    // base case
    if (n <= 1)
        return n;
  
    // if fib(n) has already
    // been computed we do not
    // do further recursive
    // calls and hence reduce
    // the number of repeated
    // work
    if (term[n] != 0)
        return term[n];
  
    else
    {
  
        // store the computed value
        // of fib(n) in an array
        // term at index n to so that
        // it does not needs to be
        // precomputed again
        term[n] = fib(n - 1) +
                  fib(n - 2);
  
        return term[n];
    }
}
  
// Driver Code
public static void Main ()
{
    int n = 6;
    Console.Write(fib(n));
}
}


Javascript


C++
// A Naive recursive implementation of LCS problem
#include 
 
int max(int a, int b);
 
// Returns length of LCS for X[0..m-1], Y[0..n-1]
int lcs(char* X, char* Y, int m, int n)
{
    if (m == 0 || n == 0)
        return 0;
    if (X[m - 1] == Y[n - 1])
        return 1 + lcs(X, Y, m - 1, n - 1);
    else
        return max(lcs(X, Y, m, n - 1),
                  lcs(X, Y, m - 1, n));
}
 
// Utility function to get max of 2 integers
int max(int a, int b)
{
    return (a > b) ? a : b;
}
 
// Driver Code
int main()
{
    char X[] = "AGGTAB";
    char Y[] = "GXTXAYB";
 
    int m = strlen(X);
    int n = strlen(Y);
 
    printf("Length of LCS is %dn", lcs(X, Y, m, n));
 
    return 0;
}


Java
// A Naive recursive implementation of LCS problem
import java.io.*;
class GFG
{
 
    // Utility function to get max of 2 integers
    static int max(int a, int b) { return (a > b) ? a : b; }
 
    // Returns length of LCS for X[0..m-1], Y[0..n-1]
    static int lcs(String X, String Y, int m, int n)
    {
        if (m == 0 || n == 0)
            return 0;
        if (X.charAt(m - 1) == Y.charAt(n - 1))
            return 1 + lcs(X, Y, m - 1, n - 1);
        else
            return max(lcs(X, Y, m, n - 1),
                       lcs(X, Y, m - 1, n));
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        String X = "AGGTAB";
        String Y = "GXTXAYB";
 
        int m = X.length();
        int n = Y.length();
 
        System.out.print("Length of LCS is "
                         + lcs(X, Y, m, n));
    }
}
 
// This code is contributed by subhammahato348


Python3
# A Naive recursive implementation of LCS problem
 
# Returns length of LCS for X[0..m-1], Y[0..n-1]
def lcs(X, Y, m, n):
    if (m == 0 or n == 0):
        return 0;
    if (X[m - 1] == Y[n - 1]):
        return 1 + lcs(X, Y, m - 1, n - 1);
    else:
        return max(lcs(X, Y, m, n - 1),
                  lcs(X, Y, m - 1, n));
 
# Driver Code
if __name__=='__main__':
    X = "AGGTAB";
    Y = "GXTXAYB";
    m = len(X);
    n = len(Y);
    print("Length of LCS is {}n".format(lcs(X, Y, m, n)))
 
# This code is contributed by rutvik_56.


C#
// A Naive recursive implementation of LCS problem
using System;
class GFG
{
 
  // Utility function to get max of 2 integers
  static int max(int a, int b) { return (a > b) ? a : b; }
 
  // Returns length of LCS for X[0..m-1], Y[0..n-1]
  static int lcs(string X, string Y, int m, int n)
  {
    if (m == 0 || n == 0)
      return 0;
    if (X[m - 1] == Y[n - 1])
      return 1 + lcs(X, Y, m - 1, n - 1);
    else
      return max(lcs(X, Y, m, n - 1),
                 lcs(X, Y, m - 1, n));
  }
 
  // Driver Code
  public static void Main()
  {
    string X = "AGGTAB";
    string Y = "GXTXAYB";
 
    int m = X.Length;
    int n = Y.Length;
 
    Console.Write("Length of LCS is "
                  + lcs(X, Y, m, n));
  }
}
 
// This code is contributed by subhammahato348


C++
// C++ program to memoize
// recursive implementation of LCS problem
#include 
int arr[1000][1000];
int max(int a, int b);
 
// Returns length of LCS for X[0..m-1], Y[0..n-1] */
// memoization applied in recursive solution
int lcs(char* X, char* Y, int m, int n)
{
    // base case
    if (m == 0 || n == 0)
        return 0;
 
    // if the same state has already been
    // computed
    if (arr[m - 1][n - 1] != -1)
        return arr[m - 1][n - 1];
 
    // if equal, then we store the value of the
    // function call
    if (X[m - 1] == Y[n - 1]) {
 
        // store it in arr to avoid further repetitive
        // work in future function calls
        arr[m - 1][n - 1] = 1 + lcs(X, Y, m - 1, n - 1);
        return arr[m - 1][n - 1];
    }
    else {
        // store it in arr to avoid further repetitive
        // work in future function calls
        arr[m - 1][n - 1] = max(lcs(X, Y, m, n - 1),
                                lcs(X, Y, m - 1, n));
        return arr[m - 1][n - 1];
    }
}
 
// Utility function to get max of 2 integers
int max(int a, int b)
{
    return (a > b) ? a : b;
}
 
// Driver Code
int main()
{
    memset(arr, -1, sizeof(arr));
    char X[] = "AGGTAB";
    char Y[] = "GXTXAYB";
 
    int m = strlen(X);
    int n = strlen(Y);
 
    printf("Length of LCS is %d", lcs(X, Y, m, n));
 
    return 0;
}


Java
// Java program to memoize
// recursive implementation of LCS problem
import java.io.*;
import java.lang.*;
class GFG
{
  public static int arr[][] = new int[1000][1000];
 
  // Returns length of LCS for X[0..m-1], Y[0..n-1] */
  // memoization applied in recursive solution
  public static int lcs(String X, String Y, int m, int n)
  {
 
    // base case
    if (m == 0 || n == 0)
      return 0;
 
    // if the same state has already been
    // computed
    if (arr[m - 1][n - 1] != -1)
      return arr[m - 1][n - 1];
 
    // if equal, then we store the value of the
    // function call
    if ( X.charAt(m - 1) == Y.charAt(n - 1))
    {
 
      // store it in arr to avoid further repetitive
      // work in future function calls
      arr[m - 1][n - 1] = 1 + lcs(X, Y, m - 1, n - 1);
      return arr[m - 1][n - 1];
    }
    else
    {
 
      // store it in arr to avoid further repetitive
      // work in future function calls
      arr[m - 1][n - 1] = max(lcs(X, Y, m, n - 1),
                              lcs(X, Y, m - 1, n));
      return arr[m - 1][n - 1];
    }
  }
 
  // Utility function to get max of 2 integers
  public static int max(int a, int b)
  {
    return (a > b) ? a : b;
  }
 
  // Driver code
  public static void main (String[] args)
  {
    for(int i = 0; i < 1000; i++)
    {
      for(int j = 0; j < 1000; j++)
      {
        arr[i][j] = -1;
      }
    }
    String X = "AGGTAB";
    String Y = "GXTXAYB";
 
    int m = X.length();
    int n = Y.length();
 
    System.out.println("Length of LCS is " + lcs(X, Y, m, n));
  }
}
 
// This code is contributed by manupathria.


Python3
# Python3 program to memoize
# recursive implementation of LCS problem
 
# Returns length of LCS for X[0..m-1], Y[0..n-1]
# memoization applied in recursive solution
def lcs(X, Y, m, n):
 
    global arr
 
    # base case
    if (m == 0 or n == 0):
        return 0
 
    # if the same state has already been
    # computed
    if (arr[m - 1][n - 1] != -1):
        return arr[m - 1][n - 1]
 
    # if equal, then we store the value of the
    # function call
    if (X[m - 1] == Y[n - 1]):
 
        # store it in arr to avoid further repetitive
        # work in future function calls
        arr[m - 1][n - 1] = 1 + lcs(X, Y, m - 1, n - 1)
        return arr[m - 1][n - 1]
 
    else:
 
        # store it in arr to avoid further repetitive
        # work in future function calls
        arr[m - 1][n - 1] = max(lcs(X, Y, m, n - 1),
                                lcs(X, Y, m - 1, n))
        return arr[m - 1][n - 1]
 
 
# Driver code
 
arr = [[0]*1000]*1000
 
for i in range(0, 1000):
    for j in range(0, 1000):
        arr[i][j] = -1
 
X = "AGGTAB"
Y = "GXTXAYB"
 
m = len(X)
n = len(Y)
 
print("Length of LCS is ", lcs(X, Y, m, n))
 
# This code is contributed by Dharanendra L V.


C#
// C# program to memoize
// recursive implementation of LCS problem
using System;
public class GFG
{
 
  public static int[, ] arr = new int[1000, 1000];
 
  // Returns length of LCS for X[0..m-1], Y[0..n-1] */
  // memoization applied in recursive solution
  public static int lcs(String X, String Y, int m, int n)
  {
 
    // base case
    if (m == 0 || n == 0)
      return 0;
 
    // if the same state has already been
    // computed
    if (arr[m - 1, n - 1] != -1)
      return arr[m - 1, n - 1];
 
    // if equal, then we store the value of the
    // function call
    if ( X[m - 1] == Y[n - 1])
    {
 
      // store it in arr to avoid further repetitive
      // work in future function calls
      arr[m - 1, n - 1] = 1 + lcs(X, Y, m - 1, n - 1);
      return arr[m - 1, n - 1];
    }
    else
    {
 
      // store it in arr to avoid further repetitive
      // work in future function calls
      arr[m - 1, n - 1] = max(lcs(X, Y, m, n - 1),
                              lcs(X, Y, m - 1, n));
      return arr[m - 1, n - 1];
    }
  }
 
  // Utility function to get max of 2 integers
  public static int max(int a, int b)
  {
    return (a > b) ? a : b;
  }
 
  // Driver code
  static public void Main (){
 
    for(int i = 0; i < 1000; i++)
    {
      for(int j = 0; j < 1000; j++)
      {
        arr[i, j] = -1;
      }
    }
    String X = "AGGTAB";
    String Y = "GXTXAYB";
 
    int m = X.Length;
    int n = Y.Length;
 
    Console.WriteLine("Length of LCS is " + lcs(X, Y, m, n));
  }
}
 
// This code is contributed by Dharanendra L V.


C++
// A recursive implementation of LCS problem
// of three strings
#include 
int max(int a, int b);
 
// Returns length of LCS for X[0..m-1], Y[0..n-1]
int lcs(char* X, char* Y, char* Z, int m, int n, int o)
{
    // base case
    if (m == 0 || n == 0 || o == 0)
        return 0;
 
    // if equal, then check for next combination
    if (X[m - 1] == Y[n - 1] and Y[n - 1] == Z[o - 1]) {
 
        // recursive call
        return 1 + lcs(X, Y, Z, m - 1, n - 1, o - 1);
    }
    else {
 
        // return the maximum of the three other
        // possible states in recursion
        return max(lcs(X, Y, Z, m, n - 1, o),
                   max(lcs(X, Y, Z, m - 1, n, o),
                       lcs(X, Y, Z, m, n, o - 1)));
    }
}
 
// Utility function to get max of 2 integers
int max(int a, int b)
{
    return (a > b) ? a : b;
}
 
// Driver Code
int main()
{
 
    char X[] = "geeks";
    char Y[] = "geeksfor";
    char Z[] = "geeksforge";
    int m = strlen(X);
    int n = strlen(Y);
    int o = strlen(Z);
    printf("Length of LCS is %d", lcs(X, Y, Z, m, n, o));
 
    return 0;
}


Java
// A recursive implementation of LCS problem
// of three strings
class GFG
{
  // Utility function to get max of 2 integers
  static int max(int a, int b)
  {
    return (a > b) ? a : b;
  }
 
  // Returns length of LCS for X[0..m-1], Y[0..n-1]
  static int lcs(char[] X, char[] Y, char[] Z,
                 int m, int n, int o)
  {
 
    // base case
    if (m == 0 || n == 0 || o == 0)
      return 0;
 
    // if equal, then check for next combination
    if (X[m - 1] == Y[n - 1] && Y[n - 1] == Z[o - 1])
    {
 
      // recursive call
      return 1 + lcs(X, Y, Z, m - 1, n - 1, o - 1);
    }
    else
    {
 
      // return the maximum of the three other
      // possible states in recursion
      return Math.max(lcs(X, Y, Z, m, n - 1, o),
                      Math.max(lcs(X, Y, Z, m - 1, n, o),
                               lcs(X, Y, Z, m, n, o - 1)));
    }
  }
 
  // Driver code
  public static void main(String[] args)
  {
    char[] X = "geeks".toCharArray();
    char[] Y = "geeksfor".toCharArray();
    char[] Z = "geeksforge".toCharArray();
    int m = X.length;
    int n = Y.length;
    int o = Z.length;
    System.out.println("Length of LCS is " + lcs(X, Y, Z, m, n, o));
  }
}
 
// This code is contributed by divyesh072019.


C#
// A recursive implementation of LCS problem
// of three strings
using System;
class GFG {
     
    // Utility function to get max of 2 integers
    static int max(int a, int b)
    {
        return (a > b) ? a : b;
    }
 
    // Returns length of LCS for X[0..m-1], Y[0..n-1]
    static int lcs(char[] X, char[] Y, char[] Z, int m, int n, int o)
    {
       
        // base case
        if (m == 0 || n == 0 || o == 0)
            return 0;
      
        // if equal, then check for next combination
        if (X[m - 1] == Y[n - 1] && Y[n - 1] == Z[o - 1])
        {
      
            // recursive call
            return 1 + lcs(X, Y, Z, m - 1, n - 1, o - 1);
        }
        else
        {
      
            // return the maximum of the three other
            // possible states in recursion
            return Math.Max(lcs(X, Y, Z, m, n - 1, o),
                       Math.Max(lcs(X, Y, Z, m - 1, n, o),
                           lcs(X, Y, Z, m, n, o - 1)));
        }
    }
 
  // Driver code
  static void Main()
  {
    char[] X = "geeks".ToCharArray();
    char[] Y = "geeksfor".ToCharArray();
    char[] Z = "geeksforge".ToCharArray();
    int m = X.Length;
    int n = Y.Length;
    int o = Z.Length;
    Console.WriteLine("Length of LCS is " + lcs(X, Y, Z, m, n, o));
  }
}
 
// This code is contributed by divyeshrabadiya07


C++
// A memoize recursive implementation of LCS problem
#include 
int arr[100][100][100];
int max(int a, int b);
 
// Returns length of LCS for X[0..m-1], Y[0..n-1] */
// memoization applied in recursive solution
int lcs(char* X, char* Y, char* Z, int m, int n, int o)
{
    // base case
    if (m == 0 || n == 0 || o == 0)
        return 0;
 
    // if the same state has already been
    // computed
    if (arr[m - 1][n - 1][o - 1] != -1)
        return arr[m - 1][n - 1][o - 1];
 
    // if equal, then we store the value of the
    // fucntion call
    if (X[m - 1] == Y[n - 1] and Y[n - 1] == Z[o - 1]) {
 
        // store it in arr to avoid further repetitive work
        // in future function calls
        arr[m - 1][n - 1][o - 1] = 1 + lcs(X, Y, Z, m - 1,
                                            n - 1, o - 1);
        return arr[m - 1][n - 1][o - 1];
    }
    else {
 
        // store it in arr to avoid further repetitive work
        // in future function calls
        arr[m - 1][n - 1][o - 1] =
                               max(lcs(X, Y, Z, m, n - 1, o),
                                 max(lcs(X, Y, Z, m - 1, n, o),
                                    lcs(X, Y, Z, m, n, o - 1)));
        return arr[m - 1][n - 1][o - 1];
    }
}
 
// Utility function to get max of 2 integers
int max(int a, int b)
{
    return (a > b) ? a : b;
}
 
// Driver Code
int main()
{
    memset(arr, -1, sizeof(arr));
    char X[] = "geeks";
    char Y[] = "geeksfor";
    char Z[] = "geeksforgeeks";
    int m = strlen(X);
    int n = strlen(Y);
    int o = strlen(Z);
    printf("Length of LCS is %d", lcs(X, Y, Z, m, n, o));
 
    return 0;
}


Java
// A memoize recursive implementation of LCS problem
import java.io.*;
class GFG
{
   
  public static int[][][] arr = new int[100][100][100];
 
  // Returns length of LCS for X[0..m-1], Y[0..n-1] */
  // memoization applied in recursive solution
  static int lcs(String X, String Y, String Z,
                 int m, int n, int o)
  {
     
      // base case
      if (m == 0 || n == 0 || o == 0)
          return 0;
 
      // if the same state has already been
      // computed
      if (arr[m - 1][n - 1][o - 1] != -1)
          return arr[m - 1][n - 1][o - 1];
 
      // if equal, then we store the value of the
      // fucntion call
      if (X.charAt(m - 1) == Y.charAt(n - 1) &&
          Y.charAt(n - 1) == Z.charAt(o - 1)) {
 
          // store it in arr to avoid further repetitive work
          // in future function calls
          arr[m - 1][n - 1][o - 1] = 1 + lcs(X, Y, Z, m - 1,
                                              n - 1, o - 1);
          return arr[m - 1][n - 1][o - 1];
      }
      else
      {
 
          // store it in arr to avoid further repetitive work
          // in future function calls
          arr[m - 1][n - 1][o - 1] =
                                 max(lcs(X, Y, Z, m, n - 1, o),
                                   max(lcs(X, Y, Z, m - 1, n, o),
                                      lcs(X, Y, Z, m, n, o - 1)));
          return arr[m - 1][n - 1][o - 1];
      }
  }
 
  // Utility function to get max of 2 integers
  static int max(int a, int b)
  {
      return (a > b) ? a : b;
  }
 
  // Driver Code
  public static void main (String[] args)
  { 
    for(int i = 0; i < 100; i++)
    {
      for(int j = 0; j < 100; j++)
      {
        for(int k = 0; k < 100; k++)
        {
          arr[i][j][k] = -1;
        }
      }
    }
     
    String X = "geeks";
    String Y = "geeksfor";
    String Z = "geeksforgeeks";
    int m = X.length();
    int n = Y.length();
    int o = Z.length();
    System.out.print("Length of LCS is " + lcs(X, Y, Z, m, n, o));
  }
}
 
// This code is contributed by Dharanendra L V.


Python3
# A memoize recursive implementation of LCS problem
 
# Returns length of LCS for X[0..m-1], Y[0..n-1] */
# memoization applied in recursive solution
def lcs(X, Y, Z, m, n, o):
    global arr
 
    # base case
    if(m == 0 or n == 0 or o == 0):
        return 0
 
    # if the same state has already been
    # computed
    if (arr[m - 1][n - 1][o - 1] != -1):
        return arr[m - 1][n - 1][o - 1]
 
    # if equal, then we store the value of the
    # fucntion call
    if (X[m - 1] == Y[n - 1] and
            Y[n - 1] == Z[o - 1]):
 
        # store it in arr to avoid further repetitive work
        # in future function calls
        arr[m - 1][n - 1][o - 1] = 1 + lcs(X, Y, Z, m - 1,
                                           n - 1, o - 1)
        return arr[m - 1][n - 1][o - 1]
 
    else:
 
        # store it in arr to avoid further repetitive work
        # in future function calls
        arr[m - 1][n - 1][o - 1] = max(lcs(X, Y, Z, m, n - 1, o),
                                       max(lcs(X, Y, Z, m - 1, n, o), lcs(X, Y, Z, m, n, o - 1)))
        return arr[m - 1][n - 1][o - 1]
 
# Driver Code
arr = [[[0 for k in range(100)] for j in range(100)] for i in range(100)]
 
for i in range(100):
    for j in range(100):
        for k in range(100):
            arr[i][j][k] = -1
 
X = "geeks"
Y = "geeksfor"
Z = "geeksforgeeks"
m = len(X)
n = len(Y)
o = len(Z)
print("Length of LCS is ", lcs(X, Y, Z, m, n, o))
 
# This code is contributed by Dharanendra L V.


C#
// A memoize recursive implementation of LCS problem
using System;
public class GFG{
 
  public static int[, , ] arr = new int[100, 100, 100];
 
  // Returns length of LCS for X[0..m-1], Y[0..n-1] */
  // memoization applied in recursive solution
  static int lcs(String X, String Y, String Z, int m, int n, int o)
  {
      // base case
      if (m == 0 || n == 0 || o == 0)
          return 0;
 
      // if the same state has already been
      // computed
      if (arr[m - 1, n - 1, o - 1] != -1)
          return arr[m - 1, n - 1, o - 1];
 
      // if equal, then we store the value of the
      // fucntion call
      if (X[m - 1] == Y[n - 1] &&
          Y[n - 1] == Z[o - 1]) {
 
          // store it in arr to avoid further repetitive work
          // in future function calls
          arr[m - 1, n - 1, o - 1] = 1 + lcs(X, Y, Z, m - 1,
                                              n - 1, o - 1);
          return arr[m - 1, n - 1, o - 1];
      }
      else {
 
          // store it in arr to avoid further repetitive work
          // in future function calls
          arr[m - 1, n - 1, o - 1] =
                                 max(lcs(X, Y, Z, m, n - 1, o),
                                   max(lcs(X, Y, Z, m - 1, n, o),
                                      lcs(X, Y, Z, m, n, o - 1)));
          return arr[m - 1, n - 1, o - 1];
      }
  }
 
  // Utility function to get max of 2 integers
  static int max(int a, int b)
  {
      return (a > b) ? a : b;
  }
 
  // Driver Code
  static public void Main (){
 
    for(int i = 0; i < 100; i++) {
      for(int j = 0; j < 100; j++) {
        for(int k = 0; k < 100; k++) {
          arr[i, j, k] = -1;
        }
      }
    }
     
    String X = "geeks";
    String Y = "geeksfor";
    String Z = "geeksforgeeks";
    int m = X.Length;
    int n = Y.Length;
    int o = Z.Length;
    Console.WriteLine("Length of LCS is " + lcs(X, Y, Z, m, n, o));
  }
}
 
// This code is contributed by Dharanendra L V.


输出:
8

一个普遍的观察是,此实现做了很多重复的工作(请参见下面的递归树)。因此,这将花费大量时间来找到第N个斐波那契数。

fib(5)   
                     /                 \        
               fib(4)                  fib(3)   
             /      \                /       \
         fib(3)      fib(2)         fib(2)    fib(1)
        /   \          /    \       /      \ 
  fib(2)   fib(1)  fib(1) fib(0) fib(1) fib(0)
  /    \ 
fib(1) fib(0) 

In the above tree fib(3), fib(2), fib(1), fib(0) all are called more then once.

使用制表法已经解决了以下问题。
在下面的程序中,解释了编写自顶向下方法程序的步骤。递归程序中的某些修改将降低程序的复杂度并提供所需的结果。如果fib(x)以前未发生过,则我们将fib(x)的值存储在索引为x的数组项中,并返回term [x] 。通过记录数组索引x处的fib(x)的返回值,减少了已调用fib(x)的下一步的递归调用次数。因此,无需进行进一步的递归调用来计算fib(x)的值,则在先前已经计算过fib(x)时返回term [x],以避免如树中所示的许多重复工作。
下面给出的是记忆的递归代码,用于查找第N个项。

C++

// CPP program to find the Nth term
// of Fibonacci series
#include 
using namespace std;
int term[1000];
// Fibonacci Series using memoized Recursion
int fib(int n)
{
    // base case
    if (n <= 1)
        return n;
 
    // if fib(n) has already been computed
    // we do not do further recursive calls
    // and hence reduce the number of repeated
    // work
    if (term[n] != 0)
        return term[n];
 
    else {
 
        // store the computed value of fib(n)
        // in an array term at index n to
        // so that it does not needs to be
        // precomputed again
        term[n] = fib(n - 1) + fib(n - 2);
 
        return term[n];
    }
}
 
// Driver Code
int main()
{
    int n = 6;
    printf("%d", fib(n));
    return 0;
}

Java

// Java program to find
// the Nth term of
// Fibonacci series
import java.io.*;
 
class GFG
{
 
static  int []term = new int [1000];
// Fibonacci Series using
// memoized Recursion
static int fib(int n)
{
    // base case
    if (n <= 1)
        return n;
 
    // if fib(n) has already
    // been computed we do not
    // do further recursive
    // calls and hence reduce
    // the number of repeated
    // work
    if (term[n] != 0)
        return term[n];
 
    else
    {
 
        // store the computed value
        // of fib(n) in an array
        // term at index n to so that
        // it does not needs to be
        // precomputed again
        term[n] = fib(n - 1) +
                  fib(n - 2);
 
        return term[n];
    }
}
 
// Driver Code
public static void main (String[] args)
{
    int n = 6;
    System.out.println(fib(n));
}
}
 
// This code is contributed by ajit

Python3

# Python program to find the Nth term
# of Fibonacci series
term = [0 for i in range(1000)]
 
# Fibonacci Series using memoized Recursion
def fib(n):
   
  # base case
  if n <= 1:
    return n
 
  # if fib(n) has already been computed
  # we do not do further recursive calls
  # and hence reduce the number of repeated
  # work
  if term[n] != 0:
    return term[n]
 
  else:
     
    # store the computed value of fib(n)
    # in an array term at index n to
    # so that it does not needs to be
    # precomputed again
    term[n] = fib(n - 1) + fib(n - 2)
    return term[n]
 
# Driver Code
n = 6
print(fib(n))
 
# This code is contributed by rohitsingh07052

C#

// C# program to find
// the Nth term of
// Fibonacci series
 
using System;
class GFG
{
      
// Fibonacci Series using
// memoized Recursion
static int fib(int n)
{
    int[] term = new int [1000];
      
    // base case
    if (n <= 1)
        return n;
  
    // if fib(n) has already
    // been computed we do not
    // do further recursive
    // calls and hence reduce
    // the number of repeated
    // work
    if (term[n] != 0)
        return term[n];
  
    else
    {
  
        // store the computed value
        // of fib(n) in an array
        // term at index n to so that
        // it does not needs to be
        // precomputed again
        term[n] = fib(n - 1) +
                  fib(n - 2);
  
        return term[n];
    }
}
  
// Driver Code
public static void Main ()
{
    int n = 6;
    Console.Write(fib(n));
}
}

Java脚本


输出:
8

如果递归代码已经编写了一次,则备忘录只是修改递归程序并存储返回值,以避免重复调用先前已计算的函数。

二维记忆

在上面的程序中,递归函数只有一个参数,该参数在每次调用函数后的值都不恒定。下面显示了一个递归程序具有两个非恒定参数的实现。
例如,给出两个字符串时,用于解决标准动态问题LCS问题的程序。该问题的一般递归解决方案是生成两个给定序列的所有子序列,并找到最长的匹配子序列。总共可能的组合为2 n 。因此,递归解将采用O(2 n ) 。此处讨论了编写递归解决方案的方法。
下面给出的是LCS问题的递归解决方案:

C++

// A Naive recursive implementation of LCS problem
#include 
 
int max(int a, int b);
 
// Returns length of LCS for X[0..m-1], Y[0..n-1]
int lcs(char* X, char* Y, int m, int n)
{
    if (m == 0 || n == 0)
        return 0;
    if (X[m - 1] == Y[n - 1])
        return 1 + lcs(X, Y, m - 1, n - 1);
    else
        return max(lcs(X, Y, m, n - 1),
                  lcs(X, Y, m - 1, n));
}
 
// Utility function to get max of 2 integers
int max(int a, int b)
{
    return (a > b) ? a : b;
}
 
// Driver Code
int main()
{
    char X[] = "AGGTAB";
    char Y[] = "GXTXAYB";
 
    int m = strlen(X);
    int n = strlen(Y);
 
    printf("Length of LCS is %dn", lcs(X, Y, m, n));
 
    return 0;
}

Java

// A Naive recursive implementation of LCS problem
import java.io.*;
class GFG
{
 
    // Utility function to get max of 2 integers
    static int max(int a, int b) { return (a > b) ? a : b; }
 
    // Returns length of LCS for X[0..m-1], Y[0..n-1]
    static int lcs(String X, String Y, int m, int n)
    {
        if (m == 0 || n == 0)
            return 0;
        if (X.charAt(m - 1) == Y.charAt(n - 1))
            return 1 + lcs(X, Y, m - 1, n - 1);
        else
            return max(lcs(X, Y, m, n - 1),
                       lcs(X, Y, m - 1, n));
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        String X = "AGGTAB";
        String Y = "GXTXAYB";
 
        int m = X.length();
        int n = Y.length();
 
        System.out.print("Length of LCS is "
                         + lcs(X, Y, m, n));
    }
}
 
// This code is contributed by subhammahato348

Python3

# A Naive recursive implementation of LCS problem
 
# Returns length of LCS for X[0..m-1], Y[0..n-1]
def lcs(X, Y, m, n):
    if (m == 0 or n == 0):
        return 0;
    if (X[m - 1] == Y[n - 1]):
        return 1 + lcs(X, Y, m - 1, n - 1);
    else:
        return max(lcs(X, Y, m, n - 1),
                  lcs(X, Y, m - 1, n));
 
# Driver Code
if __name__=='__main__':
    X = "AGGTAB";
    Y = "GXTXAYB";
    m = len(X);
    n = len(Y);
    print("Length of LCS is {}n".format(lcs(X, Y, m, n)))
 
# This code is contributed by rutvik_56.

C#

// A Naive recursive implementation of LCS problem
using System;
class GFG
{
 
  // Utility function to get max of 2 integers
  static int max(int a, int b) { return (a > b) ? a : b; }
 
  // Returns length of LCS for X[0..m-1], Y[0..n-1]
  static int lcs(string X, string Y, int m, int n)
  {
    if (m == 0 || n == 0)
      return 0;
    if (X[m - 1] == Y[n - 1])
      return 1 + lcs(X, Y, m - 1, n - 1);
    else
      return max(lcs(X, Y, m, n - 1),
                 lcs(X, Y, m - 1, n));
  }
 
  // Driver Code
  public static void Main()
  {
    string X = "AGGTAB";
    string Y = "GXTXAYB";
 
    int m = X.Length;
    int n = Y.Length;
 
    Console.Write("Length of LCS is "
                  + lcs(X, Y, m, n));
  }
}
 
// This code is contributed by subhammahato348
输出:

Length of LCS is 4n

考虑到以上实现,以下是输入字符串“ AXYT”和“ AYZX”的部分递归树

lcs("AXYT", "AYZX")
                       /                 \
         lcs("AXY", "AYZX")            lcs("AXYT", "AYZ")
         /           \                   /               \
lcs("AX", "AYZX") lcs("AXY", "AYZ")   lcs("AXY", "AYZ") lcs("AXYT", "AY")

在上面的部分递归树中, lcs(“ AXY”,“ AYZ”)被求解两次。在绘制完整的递归树时,已经观察到有很多子问题可以一次又一次地解决。因此,此问题具有“重叠子结构”属性,可以通过使用“记忆化”或“制表”来避免相同子问题的重新计算。在此已经讨论了制表方法。
在递归代码中使用记忆的一个常见观察点是每个函数调用中的两个非恒定参数M和N。该函数具有4个自变量,但2个自变量是常量,不会影响备注。重复调用发生在先前已调用的N和M上。因此,当字符串索引从0开始时,使用2-D数组将计算的lcs(m,n)值存储在arr [m-1] [n-1]。每当调用具有相同参数m和n的函数时再次,我们不再执行任何递归调用,并返回arr [m-1] [n-1],因为先前对lcs(m,n)的计算已经存储在arr [m-1] [n-1 ],从而减少了发生一次以上的递归调用。
下面是递归代码的“记忆化”方法的实现。

C++

// C++ program to memoize
// recursive implementation of LCS problem
#include 
int arr[1000][1000];
int max(int a, int b);
 
// Returns length of LCS for X[0..m-1], Y[0..n-1] */
// memoization applied in recursive solution
int lcs(char* X, char* Y, int m, int n)
{
    // base case
    if (m == 0 || n == 0)
        return 0;
 
    // if the same state has already been
    // computed
    if (arr[m - 1][n - 1] != -1)
        return arr[m - 1][n - 1];
 
    // if equal, then we store the value of the
    // function call
    if (X[m - 1] == Y[n - 1]) {
 
        // store it in arr to avoid further repetitive
        // work in future function calls
        arr[m - 1][n - 1] = 1 + lcs(X, Y, m - 1, n - 1);
        return arr[m - 1][n - 1];
    }
    else {
        // store it in arr to avoid further repetitive
        // work in future function calls
        arr[m - 1][n - 1] = max(lcs(X, Y, m, n - 1),
                                lcs(X, Y, m - 1, n));
        return arr[m - 1][n - 1];
    }
}
 
// Utility function to get max of 2 integers
int max(int a, int b)
{
    return (a > b) ? a : b;
}
 
// Driver Code
int main()
{
    memset(arr, -1, sizeof(arr));
    char X[] = "AGGTAB";
    char Y[] = "GXTXAYB";
 
    int m = strlen(X);
    int n = strlen(Y);
 
    printf("Length of LCS is %d", lcs(X, Y, m, n));
 
    return 0;
}

Java

// Java program to memoize
// recursive implementation of LCS problem
import java.io.*;
import java.lang.*;
class GFG
{
  public static int arr[][] = new int[1000][1000];
 
  // Returns length of LCS for X[0..m-1], Y[0..n-1] */
  // memoization applied in recursive solution
  public static int lcs(String X, String Y, int m, int n)
  {
 
    // base case
    if (m == 0 || n == 0)
      return 0;
 
    // if the same state has already been
    // computed
    if (arr[m - 1][n - 1] != -1)
      return arr[m - 1][n - 1];
 
    // if equal, then we store the value of the
    // function call
    if ( X.charAt(m - 1) == Y.charAt(n - 1))
    {
 
      // store it in arr to avoid further repetitive
      // work in future function calls
      arr[m - 1][n - 1] = 1 + lcs(X, Y, m - 1, n - 1);
      return arr[m - 1][n - 1];
    }
    else
    {
 
      // store it in arr to avoid further repetitive
      // work in future function calls
      arr[m - 1][n - 1] = max(lcs(X, Y, m, n - 1),
                              lcs(X, Y, m - 1, n));
      return arr[m - 1][n - 1];
    }
  }
 
  // Utility function to get max of 2 integers
  public static int max(int a, int b)
  {
    return (a > b) ? a : b;
  }
 
  // Driver code
  public static void main (String[] args)
  {
    for(int i = 0; i < 1000; i++)
    {
      for(int j = 0; j < 1000; j++)
      {
        arr[i][j] = -1;
      }
    }
    String X = "AGGTAB";
    String Y = "GXTXAYB";
 
    int m = X.length();
    int n = Y.length();
 
    System.out.println("Length of LCS is " + lcs(X, Y, m, n));
  }
}
 
// This code is contributed by manupathria.

Python3

# Python3 program to memoize
# recursive implementation of LCS problem
 
# Returns length of LCS for X[0..m-1], Y[0..n-1]
# memoization applied in recursive solution
def lcs(X, Y, m, n):
 
    global arr
 
    # base case
    if (m == 0 or n == 0):
        return 0
 
    # if the same state has already been
    # computed
    if (arr[m - 1][n - 1] != -1):
        return arr[m - 1][n - 1]
 
    # if equal, then we store the value of the
    # function call
    if (X[m - 1] == Y[n - 1]):
 
        # store it in arr to avoid further repetitive
        # work in future function calls
        arr[m - 1][n - 1] = 1 + lcs(X, Y, m - 1, n - 1)
        return arr[m - 1][n - 1]
 
    else:
 
        # store it in arr to avoid further repetitive
        # work in future function calls
        arr[m - 1][n - 1] = max(lcs(X, Y, m, n - 1),
                                lcs(X, Y, m - 1, n))
        return arr[m - 1][n - 1]
 
 
# Driver code
 
arr = [[0]*1000]*1000
 
for i in range(0, 1000):
    for j in range(0, 1000):
        arr[i][j] = -1
 
X = "AGGTAB"
Y = "GXTXAYB"
 
m = len(X)
n = len(Y)
 
print("Length of LCS is ", lcs(X, Y, m, n))
 
# This code is contributed by Dharanendra L V.

C#

// C# program to memoize
// recursive implementation of LCS problem
using System;
public class GFG
{
 
  public static int[, ] arr = new int[1000, 1000];
 
  // Returns length of LCS for X[0..m-1], Y[0..n-1] */
  // memoization applied in recursive solution
  public static int lcs(String X, String Y, int m, int n)
  {
 
    // base case
    if (m == 0 || n == 0)
      return 0;
 
    // if the same state has already been
    // computed
    if (arr[m - 1, n - 1] != -1)
      return arr[m - 1, n - 1];
 
    // if equal, then we store the value of the
    // function call
    if ( X[m - 1] == Y[n - 1])
    {
 
      // store it in arr to avoid further repetitive
      // work in future function calls
      arr[m - 1, n - 1] = 1 + lcs(X, Y, m - 1, n - 1);
      return arr[m - 1, n - 1];
    }
    else
    {
 
      // store it in arr to avoid further repetitive
      // work in future function calls
      arr[m - 1, n - 1] = max(lcs(X, Y, m, n - 1),
                              lcs(X, Y, m - 1, n));
      return arr[m - 1, n - 1];
    }
  }
 
  // Utility function to get max of 2 integers
  public static int max(int a, int b)
  {
    return (a > b) ? a : b;
  }
 
  // Driver code
  static public void Main (){
 
    for(int i = 0; i < 1000; i++)
    {
      for(int j = 0; j < 1000; j++)
      {
        arr[i, j] = -1;
      }
    }
    String X = "AGGTAB";
    String Y = "GXTXAYB";
 
    int m = X.Length;
    int n = Y.Length;
 
    Console.WriteLine("Length of LCS is " + lcs(X, Y, m, n));
  }
}
 
// This code is contributed by Dharanendra L V.
输出:
Length of LCS is 4

3-D记忆

在上面的程序,递归函数只有两个参数,其值分别为:不是每个函数调用之后维持恒定。下面,实现了递归程序具有三个非恒定参数的实现。
例如,用于解决三个字符串的标准动态问题LCS问题的程序。该问题的一般递归解决方案是生成两个给定序列的所有子序列,并找到最长的匹配子序列。总共可能的组合为3 n 。因此,递归解将采用O(3 n )
下面给出的是LCS问题的递归解决方案:

C++

// A recursive implementation of LCS problem
// of three strings
#include 
int max(int a, int b);
 
// Returns length of LCS for X[0..m-1], Y[0..n-1]
int lcs(char* X, char* Y, char* Z, int m, int n, int o)
{
    // base case
    if (m == 0 || n == 0 || o == 0)
        return 0;
 
    // if equal, then check for next combination
    if (X[m - 1] == Y[n - 1] and Y[n - 1] == Z[o - 1]) {
 
        // recursive call
        return 1 + lcs(X, Y, Z, m - 1, n - 1, o - 1);
    }
    else {
 
        // return the maximum of the three other
        // possible states in recursion
        return max(lcs(X, Y, Z, m, n - 1, o),
                   max(lcs(X, Y, Z, m - 1, n, o),
                       lcs(X, Y, Z, m, n, o - 1)));
    }
}
 
// Utility function to get max of 2 integers
int max(int a, int b)
{
    return (a > b) ? a : b;
}
 
// Driver Code
int main()
{
 
    char X[] = "geeks";
    char Y[] = "geeksfor";
    char Z[] = "geeksforge";
    int m = strlen(X);
    int n = strlen(Y);
    int o = strlen(Z);
    printf("Length of LCS is %d", lcs(X, Y, Z, m, n, o));
 
    return 0;
}

Java

// A recursive implementation of LCS problem
// of three strings
class GFG
{
  // Utility function to get max of 2 integers
  static int max(int a, int b)
  {
    return (a > b) ? a : b;
  }
 
  // Returns length of LCS for X[0..m-1], Y[0..n-1]
  static int lcs(char[] X, char[] Y, char[] Z,
                 int m, int n, int o)
  {
 
    // base case
    if (m == 0 || n == 0 || o == 0)
      return 0;
 
    // if equal, then check for next combination
    if (X[m - 1] == Y[n - 1] && Y[n - 1] == Z[o - 1])
    {
 
      // recursive call
      return 1 + lcs(X, Y, Z, m - 1, n - 1, o - 1);
    }
    else
    {
 
      // return the maximum of the three other
      // possible states in recursion
      return Math.max(lcs(X, Y, Z, m, n - 1, o),
                      Math.max(lcs(X, Y, Z, m - 1, n, o),
                               lcs(X, Y, Z, m, n, o - 1)));
    }
  }
 
  // Driver code
  public static void main(String[] args)
  {
    char[] X = "geeks".toCharArray();
    char[] Y = "geeksfor".toCharArray();
    char[] Z = "geeksforge".toCharArray();
    int m = X.length;
    int n = Y.length;
    int o = Z.length;
    System.out.println("Length of LCS is " + lcs(X, Y, Z, m, n, o));
  }
}
 
// This code is contributed by divyesh072019.

C#

// A recursive implementation of LCS problem
// of three strings
using System;
class GFG {
     
    // Utility function to get max of 2 integers
    static int max(int a, int b)
    {
        return (a > b) ? a : b;
    }
 
    // Returns length of LCS for X[0..m-1], Y[0..n-1]
    static int lcs(char[] X, char[] Y, char[] Z, int m, int n, int o)
    {
       
        // base case
        if (m == 0 || n == 0 || o == 0)
            return 0;
      
        // if equal, then check for next combination
        if (X[m - 1] == Y[n - 1] && Y[n - 1] == Z[o - 1])
        {
      
            // recursive call
            return 1 + lcs(X, Y, Z, m - 1, n - 1, o - 1);
        }
        else
        {
      
            // return the maximum of the three other
            // possible states in recursion
            return Math.Max(lcs(X, Y, Z, m, n - 1, o),
                       Math.Max(lcs(X, Y, Z, m - 1, n, o),
                           lcs(X, Y, Z, m, n, o - 1)));
        }
    }
 
  // Driver code
  static void Main()
  {
    char[] X = "geeks".ToCharArray();
    char[] Y = "geeksfor".ToCharArray();
    char[] Z = "geeksforge".ToCharArray();
    int m = X.Length;
    int n = Y.Length;
    int o = Z.Length;
    Console.WriteLine("Length of LCS is " + lcs(X, Y, Z, m, n, o));
  }
}
 
// This code is contributed by divyeshrabadiya07
输出:
Length of LCS is 5

列表方法已在此处显示。在完全绘制递归树时,已经注意到存在许多重叠的子问题,这些子问题被多次计算。由于函数参数具有三个非恒定参数,因此将使用3-D数组存储当lcs(x,y,z,m,n,o)表示m,n和n的任何值时返回的值。调用了o,因此如果再次调用lcs(x,y,z,m,n,o)来获得相同的m,n和o值,则该函数将返回已存储的值,因为先前已在递归调用。 arr [m] [n] [o]存储由lcs(x,y,z,m,n,o)函数调用返回的值。递归程序中唯一需要做的修改是存储递归函数的(m,n,o)状态的返回值。其余的在上面的递归程序中保持不变。
下面是递归代码的“记忆”方法的实现:

C++

// A memoize recursive implementation of LCS problem
#include 
int arr[100][100][100];
int max(int a, int b);
 
// Returns length of LCS for X[0..m-1], Y[0..n-1] */
// memoization applied in recursive solution
int lcs(char* X, char* Y, char* Z, int m, int n, int o)
{
    // base case
    if (m == 0 || n == 0 || o == 0)
        return 0;
 
    // if the same state has already been
    // computed
    if (arr[m - 1][n - 1][o - 1] != -1)
        return arr[m - 1][n - 1][o - 1];
 
    // if equal, then we store the value of the
    // fucntion call
    if (X[m - 1] == Y[n - 1] and Y[n - 1] == Z[o - 1]) {
 
        // store it in arr to avoid further repetitive work
        // in future function calls
        arr[m - 1][n - 1][o - 1] = 1 + lcs(X, Y, Z, m - 1,
                                            n - 1, o - 1);
        return arr[m - 1][n - 1][o - 1];
    }
    else {
 
        // store it in arr to avoid further repetitive work
        // in future function calls
        arr[m - 1][n - 1][o - 1] =
                               max(lcs(X, Y, Z, m, n - 1, o),
                                 max(lcs(X, Y, Z, m - 1, n, o),
                                    lcs(X, Y, Z, m, n, o - 1)));
        return arr[m - 1][n - 1][o - 1];
    }
}
 
// Utility function to get max of 2 integers
int max(int a, int b)
{
    return (a > b) ? a : b;
}
 
// Driver Code
int main()
{
    memset(arr, -1, sizeof(arr));
    char X[] = "geeks";
    char Y[] = "geeksfor";
    char Z[] = "geeksforgeeks";
    int m = strlen(X);
    int n = strlen(Y);
    int o = strlen(Z);
    printf("Length of LCS is %d", lcs(X, Y, Z, m, n, o));
 
    return 0;
}

Java

// A memoize recursive implementation of LCS problem
import java.io.*;
class GFG
{
   
  public static int[][][] arr = new int[100][100][100];
 
  // Returns length of LCS for X[0..m-1], Y[0..n-1] */
  // memoization applied in recursive solution
  static int lcs(String X, String Y, String Z,
                 int m, int n, int o)
  {
     
      // base case
      if (m == 0 || n == 0 || o == 0)
          return 0;
 
      // if the same state has already been
      // computed
      if (arr[m - 1][n - 1][o - 1] != -1)
          return arr[m - 1][n - 1][o - 1];
 
      // if equal, then we store the value of the
      // fucntion call
      if (X.charAt(m - 1) == Y.charAt(n - 1) &&
          Y.charAt(n - 1) == Z.charAt(o - 1)) {
 
          // store it in arr to avoid further repetitive work
          // in future function calls
          arr[m - 1][n - 1][o - 1] = 1 + lcs(X, Y, Z, m - 1,
                                              n - 1, o - 1);
          return arr[m - 1][n - 1][o - 1];
      }
      else
      {
 
          // store it in arr to avoid further repetitive work
          // in future function calls
          arr[m - 1][n - 1][o - 1] =
                                 max(lcs(X, Y, Z, m, n - 1, o),
                                   max(lcs(X, Y, Z, m - 1, n, o),
                                      lcs(X, Y, Z, m, n, o - 1)));
          return arr[m - 1][n - 1][o - 1];
      }
  }
 
  // Utility function to get max of 2 integers
  static int max(int a, int b)
  {
      return (a > b) ? a : b;
  }
 
  // Driver Code
  public static void main (String[] args)
  { 
    for(int i = 0; i < 100; i++)
    {
      for(int j = 0; j < 100; j++)
      {
        for(int k = 0; k < 100; k++)
        {
          arr[i][j][k] = -1;
        }
      }
    }
     
    String X = "geeks";
    String Y = "geeksfor";
    String Z = "geeksforgeeks";
    int m = X.length();
    int n = Y.length();
    int o = Z.length();
    System.out.print("Length of LCS is " + lcs(X, Y, Z, m, n, o));
  }
}
 
// This code is contributed by Dharanendra L V.

Python3

# A memoize recursive implementation of LCS problem
 
# Returns length of LCS for X[0..m-1], Y[0..n-1] */
# memoization applied in recursive solution
def lcs(X, Y, Z, m, n, o):
    global arr
 
    # base case
    if(m == 0 or n == 0 or o == 0):
        return 0
 
    # if the same state has already been
    # computed
    if (arr[m - 1][n - 1][o - 1] != -1):
        return arr[m - 1][n - 1][o - 1]
 
    # if equal, then we store the value of the
    # fucntion call
    if (X[m - 1] == Y[n - 1] and
            Y[n - 1] == Z[o - 1]):
 
        # store it in arr to avoid further repetitive work
        # in future function calls
        arr[m - 1][n - 1][o - 1] = 1 + lcs(X, Y, Z, m - 1,
                                           n - 1, o - 1)
        return arr[m - 1][n - 1][o - 1]
 
    else:
 
        # store it in arr to avoid further repetitive work
        # in future function calls
        arr[m - 1][n - 1][o - 1] = max(lcs(X, Y, Z, m, n - 1, o),
                                       max(lcs(X, Y, Z, m - 1, n, o), lcs(X, Y, Z, m, n, o - 1)))
        return arr[m - 1][n - 1][o - 1]
 
# Driver Code
arr = [[[0 for k in range(100)] for j in range(100)] for i in range(100)]
 
for i in range(100):
    for j in range(100):
        for k in range(100):
            arr[i][j][k] = -1
 
X = "geeks"
Y = "geeksfor"
Z = "geeksforgeeks"
m = len(X)
n = len(Y)
o = len(Z)
print("Length of LCS is ", lcs(X, Y, Z, m, n, o))
 
# This code is contributed by Dharanendra L V.

C#

// A memoize recursive implementation of LCS problem
using System;
public class GFG{
 
  public static int[, , ] arr = new int[100, 100, 100];
 
  // Returns length of LCS for X[0..m-1], Y[0..n-1] */
  // memoization applied in recursive solution
  static int lcs(String X, String Y, String Z, int m, int n, int o)
  {
      // base case
      if (m == 0 || n == 0 || o == 0)
          return 0;
 
      // if the same state has already been
      // computed
      if (arr[m - 1, n - 1, o - 1] != -1)
          return arr[m - 1, n - 1, o - 1];
 
      // if equal, then we store the value of the
      // fucntion call
      if (X[m - 1] == Y[n - 1] &&
          Y[n - 1] == Z[o - 1]) {
 
          // store it in arr to avoid further repetitive work
          // in future function calls
          arr[m - 1, n - 1, o - 1] = 1 + lcs(X, Y, Z, m - 1,
                                              n - 1, o - 1);
          return arr[m - 1, n - 1, o - 1];
      }
      else {
 
          // store it in arr to avoid further repetitive work
          // in future function calls
          arr[m - 1, n - 1, o - 1] =
                                 max(lcs(X, Y, Z, m, n - 1, o),
                                   max(lcs(X, Y, Z, m - 1, n, o),
                                      lcs(X, Y, Z, m, n, o - 1)));
          return arr[m - 1, n - 1, o - 1];
      }
  }
 
  // Utility function to get max of 2 integers
  static int max(int a, int b)
  {
      return (a > b) ? a : b;
  }
 
  // Driver Code
  static public void Main (){
 
    for(int i = 0; i < 100; i++) {
      for(int j = 0; j < 100; j++) {
        for(int k = 0; k < 100; k++) {
          arr[i, j, k] = -1;
        }
      }
    }
     
    String X = "geeks";
    String Y = "geeksfor";
    String Z = "geeksforgeeks";
    int m = X.Length;
    int n = Y.Length;
    int o = Z.Length;
    Console.WriteLine("Length of LCS is " + lcs(X, Y, Z, m, n, o));
  }
}
 
// This code is contributed by Dharanendra L V.
输出:
Length of LCS is 5

注意:用于记忆的数组在函数调用之前被初始化为某个值(例如-1),以标记先前是否已调用具有相同参数的函数。