如何通过改进我的递归解决方案来计算增长最长的LIS的数量,例如[1,3,5,4,7]
返回2
,其中LIS为1,3,5,7
,1,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
数组的代码并添加了评论
答案 0 :(得分:1)
子序列的计数大于增量,因为可能有多个子序列以相同的长度结束。
使用您的示例数据,当index
为1时,with
和without
均为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的总数。此外,你应该记住这一点 - 但这很容易。