Write a program that will select the longest strictly increasing subsequence from a sequence of integers.
Input
The input file will contain a sequence of integers (positive, negative, and/or zero). Each line of the input file will contain one integer.
Output
The output for this program will be a line indicating the length of the longest subsequence, a newline, a dash character (‘-’), a newline, and then the subsequence itself printed with one integer per line. If the input contains more than one longest subsequence, the output file should print the one that occurs last in the input file.
Hint: Notice that the second 8 was not included — the subsequence must be strictly increasing.
Sample Input
-7
10
9
2
3
8
8
6
Sample Output
4
-
-7
2
3
6
问题链接:UVA481 What Goes Up
问题简述:(略)
问题分析:
这是一个计算最长递增子序列的题。这个代码代码的时间复杂度是O(nlogn)。
有关原理参见参考链接。
程序说明:函数lower_bound()其时间复杂度是O(logn),用于查找第1个大于或等于指定值的数据。
参考链接:演算法笔记:Longest Increasing Subsequence
题记:(略)
AC的C++语言程序如下:
/* UVA481 What Goes Up */
#include <bits/stdc++.h>
using namespace std;
const int N = 100000;
int a[N], dp[N], pos[N], ans[N];
int main()
{
int n, cnt = 0;
while(~scanf("%d", &n)) a[cnt++] = n;
memset(dp, 0x7F, sizeof(dp));
int len = 1;
for(int i = 0; i < cnt; i++) {
int p = lower_bound(dp, dp + len, a[i]) - dp;
dp[p] = a[i];
pos[i] = p + 1;
if(p == len) len++;
}
int len2 = len;
for( int i = cnt - 1; i >= 0; i-- ) {
if( pos[i] == len2 ) {
ans[len2] = a[i];
if( --len2 == 0 ) break;
}
}
printf("%d\n-\n", len);
for( int i = 1; i <= len; i++ )
printf("%d\n", ans[i]);
return 0;
}
来源:oschina
链接:https://my.oschina.net/u/4256309/blog/3219073