我有这个代码来寻找最长的递增子序列(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,还有一些其他的,但都没有成功。
发布于 2017-11-14 05:36:58
我已经分析了您代码,并发现了您的问题:您没有用于查找具有最大和的列表的代码,您只有简单的列表搜索。我已经添加了缺失的部分,现在,代码正常工作。此外,我还编写了自己的解决方案,使用了另一种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来确定列出的。如果你需要的话,可以提问题。
#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 https://stackoverflow.com/questions/47244167
复制相似问题