我有一个算法,它运行良好。我尝试为自己解释它(http://nemo.la/?p=943),并且在这里(http://www.geeksforgeeks.org/longest-monotonically-increasing-subsequence-size-n-log-n/)以及stackoverflow上也有解释。
我想修改它以生成最长的非单调递增子序列。
对于序列30 20 20 10 10 10 10,
答案应该是4:“10 10 10 10”。
但使用nlgn版本的算法无法工作。将s初始化为包含第一个元素“30”,从第二个元素=20开始。这是发生的情况:
1. 第一步:30不大于或等于20。我们找到大于20的最小元素。新的s变成“20”。 2. 第二步:20大于或等于20。我们扩展序列,现在s包含“20 20”。 3. 第三步:10不大于或等于20。我们找到大于10的最小元素,即“20”。新的s变成“10 20”。
之后s将永远不会增长,算法将返回2而不是4。
我想修改它以生成最长的非单调递增子序列。
对于序列30 20 20 10 10 10 10,
答案应该是4:“10 10 10 10”。
但使用nlgn版本的算法无法工作。将s初始化为包含第一个元素“30”,从第二个元素=20开始。这是发生的情况:
1. 第一步:30不大于或等于20。我们找到大于20的最小元素。新的s变成“20”。 2. 第二步:20大于或等于20。我们扩展序列,现在s包含“20 20”。 3. 第三步:10不大于或等于20。我们找到大于10的最小元素,即“20”。新的s变成“10 20”。
之后s将永远不会增长,算法将返回2而不是4。
int height[100];
int s[100];
int binary_search(int first, int last, int x) {
int mid;
while (first < last) {
mid = (first + last) / 2;
if (height[s[mid]] == x)
return mid;
else if (height[s[mid]] >= x)
last = mid;
else
first = mid + 1;
}
return first; /* or last */
}
int longest_increasing_subsequence_nlgn(int n) {
int i, k, index;
memset(s, 0, sizeof(s));
index = 1;
s[1] = 0; /* s[i] = 0 is the index of the element that ends an increasing sequence of length i = 1 */
for (i = 1; i < n; i++) {
if (height[i] >= height[s[index]]) { /* larger element, extend the sequence */
index++; /* increase the length of my subsequence */
s[index] = i; /* the current doll ends my subsequence */
}
/* else find the smallest element in s >= a[i], basically insert a[i] in s such that s stays sorted */
else {
k = binary_search(1, index, height[i]);
if (height[s[k]] >= height[i]) { /* if truly >= greater */
s[k] = i;
}
}
}
return index;
}