在“最长递增子序列”的基础上对代码进行改进,输出一条最长递增子序列。 输入 每组输入包括两行,第一行为序列长度n,第二行为序列。 输出 输出最长递增子序列中的任意一条即可。 样例输入 Copy 7 1 7 3 4 9 2 3 样例输出 Copy 1 3 4 9
时间: 2023-06-20 16:03:32 浏览: 118
可以使用动态规划来解决这个问题,先记录每个位置的最长递增子序列长度,再根据这个长度从后往前推出最长递增子序列。
具体实现步骤如下:
1. 定义一个长度为 n 的数组 dp,用来记录每个位置的最长递增子序列长度。
2. 对于每个位置 i,都从 1 到 i-1 遍历一遍,如果有 j 满足 a[j] < a[i],则 dp[i] = max(dp[i], dp[j] + 1)。
3. 找到 dp 数组中的最大值 max_length,以及最大值所在的位置 max_index。
4. 从后往前遍历一遍,找到最长递增子序列。具体方法是从位置 max_index 开始,如果 dp[i] = dp[max_index] - 1 并且 a[i] < a[max_index],则将 a[i] 加入到最长递增子序列中,并将 max_index 更新为 i。
下面是代码实现:
相关问题
用C语言写出来 在“最长递增子序列”的基础上对代码进行改进,输出一条最长递增子序列。 输入 每组输入包括两行,第一行为序列长度n,第二行为序列。 输出 输出最长递增子序列中的任意一条即可。 样例输入 Copy 7 1 7 3 4 9 2 3 样例输出 Copy 1 3 4 9
首先,我们需要先求出最长递增子序列的长度,然后再根据动态规划求解的思路,回溯得到最长递增子序列。
以下是代码实现:
```c
#include <stdio.h>
#include <stdlib.h>
#define MAX_N 1000
int dp[MAX_N]; // 存储最长递增子序列的长度
int pre[MAX_N]; // 存储每个元素在最长递增子序列中的前驱
int LIS(int *seq, int n) {
int max_len = 0; // 最长递增子序列的长度
int end = 0; // 最长递增子序列的末尾元素下标
for (int i = 0; i < n; i++) {
dp[i] = 1;
pre[i] = -1;
for (int j = 0; j < i; j++) {
if (seq[j] < seq[i] && dp[j] + 1 > dp[i]) {
dp[i] = dp[j] + 1;
pre[i] = j;
}
}
if (dp[i] > max_len) {
max_len = dp[i];
end = i;
}
}
// 回溯得到最长递增子序列
int lis[MAX_N], len = 0;
while (end != -1) {
lis[len++] = seq[end];
end = pre[end];
}
// 输出最长递增子序列
for (int i = len - 1; i >= 0; i--) {
printf("%d ", lis[i]);
}
printf("\n");
return max_len;
}
int main() {
int n, seq[MAX_N];
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &seq[i]);
}
int len = LIS(seq, n);
printf("Length of LIS: %d\n", len);
return 0;
}
```
输入样例:
```
7
1 7 3 4 9 2 3
```
输出样例:
```
1 3 4 9
Length of LIS: 4
```
阅读全文