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

Counting number of longest increasing subsequences by evolving recursive solution

本文关键字:递归 计算      更新时间:2023-10-16

例如,如何通过发展我的递归解决方案来计算最长递增的 LIS 的数量[1,3,5,4,7]返回 LIS1,3,5,72和类似1,3,4,7[3,3,3,3]4LIS3并且有其中4

我递归计算 LIS,如下所示:(我可以使用记忆对其进行优化,并根据各种解决方案进一步转到 DP,然后转到分段树,但我想直观地引导自己到它们)

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这是错误的。我正在寻找一种从这里前进的方法。

更新:为count数组添加了代码并添加了注释

子序列的计数不仅仅是一个增量,因为可以有多个子序列以相同的长度结束。

使用示例数据时,当index为 1 时,withwithout均为 3。 但是,count[3]只递增一次,即使有两个子序列具有此长度,并且返回 3 作为最大长度。 当上一个调用使用它时(当index为 0 时),with将为 4 和without3。count[4]仅增加 1,即使有两个长度为 4 的子序列。

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

首先,计算从数组的第 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 的总数。另外,您应该记住这一点 - 但这很容易。