【问题标题】:Why doesn't my recursive longest increasing subsequence function work for large inputs?为什么我的递归最长递增子序列函数不适用于大输入?
【发布时间】:2019-11-23 16:03:13
【问题描述】:

我写它是为了一次处理一个测试用例。 要么在线评委耗时太长,要么返回错误答案

来源:我用来测试的problem

它非常适合小箱子:

#include <iostream>
  #include <algorithm>
  #include <vector>
  int LIS[100000];
  void LS (int *arr , int n)
  {
      if (n == 0)
      {
          LIS[0] = 1;
          return;
      }
      if (LIS[n])
      {
          return;
      }
      int i = 0;
      int max = 0;
      while (i < n)
      {
          if (arr[i] < arr[n])
          {
              LS(arr,i);
              if (LIS[i] + 1 > max)
              {
                  max = 1 + LIS[i];
              }
          }
          ++i;
      }
      LIS[n] = max;

  }
  int main()
  {
      int n;
      std::cin >> n;
      int arr[n];
      for(int i = 0 ; i < n ; ++i) std::cin >> arr[i];
      LS(arr,n-1);
      std::sort (LIS , LIS+n);
      std::cout << "\n" << LIS[n-1] << "\n";
  }

【问题讨论】:

  • int n; std::cin &gt;&gt; n; int arr[n]; - 不是有效的标准 C++。标准 C++ 不支持 VLA(可变长度数组)。不幸的是,一些编译器支持它作为扩展,但这些扩展通常可以关闭(我建议这样做)。你想要的是std::vector
  • 递归通常比迭代慢得多。在尾递归的情况下,编译器可以将其转换为迭代函数。在您的情况下,这不是尾递归。您可以将代码重写为尾递归或编写迭代函数。 dev.to/deciduously/tail-recursion-35nb

标签: c++ dynamic-programming


【解决方案1】:

你说它适用于非常小的情况..而不是堆栈溢出..

函数调用会消耗堆栈内存..

如果递归调用深度太深,栈内存耗尽,崩溃..

【讨论】:

  • 但是我已经尝试过记忆它。在那种情况下不会有内存使用吗?
  • @ChiragM 每个函数调用都会在堆栈上获得一个堆栈帧。这会很快导致堆栈溢出。
  • @ChiragM main() --> LS() --> LS() --> .....每次调用函数时,它都会使用堆栈内存..当您使用参数和局部变量,它使用堆栈内存。增加堆栈内存或减少递归函数调用深度。
【解决方案2】:

当您从std::cin 读取int n 值时,您必须为数组arr 动态分配内存,因此您应该首先声明int *arr,然后以与您相同的方式获取用户输入现在,然后使用arr = new int[n]分配内存。

当涉及到使用递归函数计算下一个值需要很长时间时,您应该考虑重新制作函数以使用尾递归,这更接近于迭代。您可以通过编写两个计算斐波那契数的程序来检查差异 - 一个是递归的,另一个是迭代的,然后检查使用这两种方法计算 ~50th 值需要多长时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-12-12
    • 2012-11-26
    • 2021-12-04
    • 1970-01-01
    • 1970-01-01
    • 2013-07-03
    相关资源
    最近更新 更多