我有这个代码用于查找最长增加子序列(LIS),但是当我测试我的代码时,我没有得到最大值,例如:
如果我输入20 1 4 3 10,答案是1 3 10,但我需要1 4 10 这是我在C代码中的代码:
#include <stdio.h>
#include <stdlib.h>
#define INT_INF 1000
int search_replace(int *lis, int left, int right, int key) {
int mid;
for (mid = (left+right)/2; left <= right; mid = (left+right)/2) {
if (lis[mid] > key) {
right = mid - 1;
} else if (lis[mid] == key) {
return mid;
} else if (mid+1 <= right && lis[mid+1] >= key) {
lis[mid+1] = key;
return mid+1;
} else {
left = mid + 1;
}
}
if (mid == left) {
lis[mid] = key;
return mid;
}
lis[mid+1] = key;
return mid+1;
}
int main() {
int size, i;
scanf(" %d", &size);
int A[size];
for(i = 0; i < size; i++){
scanf(" %d", &A[i]);
}
int tmp, lis_length = -1;
int *answer;
int LIS[size];
int index[size];
LIS[0] = A[0];
for (i = 1; i < size; ++i) {
LIS[i] = INT_INF;
}
for (i = 1; i < size; ++i) {
index[i] = search_replace(LIS, 0, i, A[i]);
if (lis_length < index[i]) {
lis_length = index[i];
}
}
answer = (int*) malloc((lis_length+1) * sizeof(int));
for (i = size-1, tmp = lis_length; i >= 0; --i) {
if (index[i] == tmp) {
answer[tmp] = A[i];
--tmp;
}
}
printf("LIS: ");
for (i = 0; i < lis_length+1; ++i) {
printf("%d ", answer[i]);
}
printf("\n");
return 0;
}
第一个输入是数组中元素的数量。
我已经尝试过这篇文章:Find the Longest Increasing Subsequence with the Maximum Sum,其他几个但没有成功。
答案 0 :(得分:0)
我已经分析了您的代码并发现了您的问题:您没有代码来查找具有最大金额的 lis ,您只需要搜索简单的 lis 。我添加了缺少的部分,现在,代码正常工作。另外,我编写了自己的解决方案,使用了另一种 lis 搜索算法,没有二进制搜索。
注意:用于查找中间值的(left+right)/2
方法存在问题 - Nearly All Binary Searches and Mergesorts are Broken 。
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define INT_INF 1000
int search_replace(int *lis, int left, int right, int key) {
int mid;
for (mid = (left+right)/2; left <= right; mid = (left+right)/2) {
if (lis[mid] > key) {
right = mid - 1;
} else if (lis[mid] == key) {
return mid;
} else if (mid+1 <= right && lis[mid+1] >= key) {
lis[mid+1] = key;
return mid+1;
} else {
left = mid + 1;
}
}
if (mid == left) {
lis[mid] = key;
return mid;
}
lis[mid+1] = key;
return mid+1;
}
int main() {
int size, i;
scanf(" %d", &size);
int A[size];
for(i = 0; i < size; i++){
scanf(" %d", &A[i]);
}
int tmp, lis_length = -1;
int LIS[size];
int index[size];
LIS[0] = A[0];
for (i = 1; i < size; ++i) {
LIS[i] = INT_INF;
}
for (i = 1; i < size; ++i) {
index[i] = search_replace(LIS, 0, i, A[i]);
if (lis_length < index[i]) {
lis_length = index[i];
}
}
//////// my addition starts
int max, j;
// INT_MAX - the maximum number of the integer type.
// The "limits.h" header is needed for this.
int prev = INT_MAX;
int answer[lis_length + 1];
// Iterating through the "index" values.
// On the each iteration, the checking all sequences
// with the same length
// and determining the max value among them.
// Starts from the lis_length and goes to the zero.
for(i = lis_length; i >= 0; i--) {
max = INT_MIN;
for(j = 0; j < size; j++) {
if( index[j] == i
&& A[j] > max
&& A[j] < prev) {
max = A[j];
}
}
answer[i] = max;
prev = max;
}
//////// my addition ends
printf("LIS: ");
for (i = 0; i < lis_length+1; ++i) {
printf("%d ", answer[i]);
}
printf("\n");
return 0;
}
我将此algorithm用于 lis 确定。如果需要,可以提出问题。
#include <stdio.h>
#include <limits.h>
int main() {
int size = 0;
int arr_nums[100];
// Initialize all array values to the one. This is the GCC feature.
int seq_lens[100] = {[0 ... 99] = 1};
// Gets input numbers.
while(scanf("%d", arr_nums + size) == 1) {
size++;
}
// Fill the seq_lens array with sequences's lenghts.
int i, j;
int lis_num = 1;
for(i = 1; i < size; i++) {
for(j = 0; j <= i; j++) {
if( arr_nums[i] > arr_nums[j]
&& (seq_lens[j] + 1 > seq_lens[i])) {
seq_lens[i] = seq_lens[j] + 1;
}
}
// Finding the LIS number (the maximum sequence length).
// If the previous LIS number is lesser then current,
// change it to the current.
if(lis_num < seq_lens[i])
lis_num = seq_lens[i];
}
// Finding the LIS with the maximum sum
int max;
// INT_MAX - the maximum number of the integer type.
// The "limits.h" header is needed for this.
int prev = INT_MAX;
int lis_arr[lis_num];
// Iterating through the seq_lens values.
// On the each iteration, the checking all sequences with the same length
// and determining the max value among them.
// Starts from the LIS (the longest sequence number)
// and goes to the one (the minimum possible sequence number).
for(i = lis_num; i > 0; i--) {
max = INT_MIN;
for(j = 0; j < size; j++) {
if( seq_lens[j] == i
&& arr_nums[j] > max
&& arr_nums[j] < prev) {
max = arr_nums[j];
}
}
lis_arr[i - 1] = max;
prev = max;
}
printf("The longest increasing sequence number is:\n%d\n", lis_num);
puts("\nThe longest increasing sequence with the max sum is: ");
for(i = 0; i < lis_num; i++) {
printf("%d ", lis_arr[i]);
}
puts("");
return 0;
}
<强>输入强>
0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15
<强>输出强>
The longest increasing sequence number is:
6
The longest increasing sequence with the max sum is:
0 4 6 9 13 15