通过演化递归解计算最长增长子序列的数量

时间:2017-11-26 12:00:36

标签: c++ algorithm recursion

如何通过改进我的递归解决方案来计算增长最长的LIS的数量,例如[1,3,5,4,7]返回2,其中LIS为1,3,5,71,3,4,7类似于{{} 1}}它是[3,3,3,3],其中LIS是4,其中有3

我按如下方式递归计算LIS :(我可以使用memoisation对其进行优化,然后根据各种解决方案进一步使用DP进行分段树,但我希望直观地引导自己)

4

我使用int numberOfLis(vector<int>& nums) { //Set the size of count to the size of num, since there cannot be an LIS greater than the size of nums vector<int> count(nums.size(), 0); //Get the size of the maximum LIS and update the frequency of how many similar sizes have been encountered in the count array int maxcount = LIS(nums, INT32_MIN, 0, count); //Return the number of occurances by looking it up in our count. return count[maxcount]; } int LIS(vector<int>& nums, int prev, int index, vector<int>& count) { if (index == nums.size()) return 0; int with = 0; //Increasing sequence, lets select it. if (nums[index] > prev) with = 1 + helper(nums, nums[index], index + 1, count); //See if we can do better without the current number int without = helper(nums, prev, index + 1, count); //Get the maximum seen so far and update the frequency in count array int maxcount = max(with, without); ++count[maxcount]; return maxcount; } 数组count来增加最大值,因为我将其视为vector<int>(nums.size(), 0),其中返回的最大值的++count[max(with,without)]将是答案。这导致count数组count计数4而非1这是错误的。我正在寻找一种从这里前进的方法。

已更新:添加了2数组的代码并添加了评论

2 个答案:

答案 0 :(得分:1)

子序列的计数大于增量,因为可能有多个子序列以相同的长度结束。

使用您的示例数据,当index为1时,withwithout均为3. count[3]仅增加一次,即使有两个具有此长度的子序列,并返回3作为最大长度。当前一次通话使用此功能时(index为0时),with将为4且without 3. count[4]仅增加1,即使有两个长度为4的子序列。

您需要更改helper,不仅返回最长子序列的长度,还要返回具有该长度的子序列的数量。

答案 1 :(得分:1)

首先,计算从数组的第k个元素开始的最长增加子序列长度。

然后,使用此数据使用类似:

int numberoflis(int k){
     if(LIS(k)==1) return 1;
     int ret = 0;
     for(int i=k+1; i<N; ++i){
         if(A[i] > A[k] && LIS(i) == LIS(k)-1){
             ret += numberoflis(i);
         }
     }
     return ret;
 }

现在你有从k点开始的最长的增长子序列。使用一个简单的循环来计算LIS的总数。此外,你应该记住这一点 - 但这很容易。