我发现很难找到如何在 n 数字中找到长度 k 的增加序列的数量。我知道它使用了 LIS 问题,我不得不以某种方式修改它,但现在得到了解决方法。它的复杂性是O(k*n^2)
DP解决方案。请给出提示并向我解释一下。
答案 0 :(得分:1)
也许有点晚,但这可能会有所帮助:
有两种算法(据我所知)用于解决此问题。我将描述具有O(n ^ 2 * k)复杂度的那个。
该算法使用DP解决方案;这是LIS问题的一个转折点。在LIS问题中,使用1D数组存储LIS的长度直到元素i,这意味着dp [i] = LIS的长度直到元素i。这将产生如下算法:
/* let dp[] be the array that stores the length of the LIS found so far.
v[] is the array of the values
LIS(0) = 1
LIS(i) = 1 + max(LIS(j) where j in [1..i-1] and v[j] < v[i]);
*/
dp[0] = 1;
for (int i=1 ; i<n ; i++)
for (int j=0 ; j<i ; j++) if (v[j] < v[i])
dp[i] = 1 + max(dp[i], dp[j]);
然后,我们可以将其带到另一个级别,然后获得长度为k的增加子序列的数量。该算法使用相同的原理。
/*
dp[i][k] -> Stores the number of subsequences of length k until character i
v[] -> The values
n -> The size of the array
K -> the number of IS we are looking for
The idea is to increment the value of this quantity, by the amount of the sequences
found in the same character and the previous length. This will be better ilustrated int
the algorithm
*/
int totalIS = 0;
for (int i=0 ; i<n ; i++) {
dp[i][1] = 1; // Number of subsequences of length 1 until element i
for (int k=2 ; k<=K ; k++) { // For all the possible sizes of subsequence until k
for (int j=0 ; j<i ; j++) if (v[j] < v[i]) {
dp[i][k] += dp[j][k-1]; // Increment the actual amount by dp[j][k-1], which means
// the amound of IS of length k-1 until char j
}
}
totalIS += dp[i][K]; // This can also be done in a separated cycle.
}
// The total amount of IS of length K is in totalIS
如果您有任何疑问,请告诉我。