最长递增子序列问题
2017-09-06 14:26
302 查看
[align=left]POJ 2533(Longest Ordered Subsequence)
[/align]
[align=center]
[/align]
[align=center]Longest Ordered Subsequence[/align]
Description
A numeric sequence of
ai is ordered if a1 < a2 < ... <
aN. Let the subsequence of the given numeric sequence (a1,
a2, ..., aN) be any sequence (ai1,
ai2, ..., aiK), where 1 <=
i1 < i2 < ... < iK <=
N. For example, sequence (1, 7, 3, 5, 9, 4, 8) has ordered subsequences, e. g., (1, 7), (3, 4, 8) and many others. All longest ordered subsequences are of length 4, e. g., (1, 3, 5, 8).
Your program, when given the numeric sequence, must find the length of its longest ordered subsequence.
Input
The first line of input file contains the length of sequence N. The second line contains the elements of sequence - N integers in the range from 0 to 10000 each, separated by spaces. 1 <= N <= 1000
Output
Output file must contain a single integer - the length of the longest ordered subsequence of the given sequence.
Sample Input
Sample Output
题目描述:题意就是求一段数字序列中的最长递增序列
解题分析:首先,样例分析有数字序列sub[1005],由于本题最大数字的长度为1000,所以此题可以允许我们在O(n^2)的 时间复杂度,对于此题,我们首先推出递推式,我们首先创立一个数组 maxt[1005],a[0]代表第一个元素,a[1]代表到第二个元素的最长递增子序列,a[2]表示到第三个元素的最长递增子序列,a[3]表示到第四个元素的最长递增子序列······所以对于第
j个元素,对于它前面的元素可遍历,有遍历元素i,如果有 sub[ j ] >
sub[ i ],则有递推式:maxt[ j ] = max( maxt[ i ]+1 , maxt[ j ] ),
AC code:
南洋理工:214
难度:4 描述:
给定一整型数列{a1,a2...,an}(0<n<=100000),找出单调递增最长子序列,并求出其长度。
如:1 9 10 5 11 2 13的最长单调递增子序列是1 9 10 11 13,长度为5。
输入:有多组测试数据(<=7)
每组测试数据的第一行是一个整数n表示序列中共有n个整数,随后的下一行里有n个整数,表示数列中的所有元素.每个整形数中间用空格间隔开(0<n<=100000)。
数据以EOF结束 。
输入数据保证合法(全为int型整数)!输出对于每组测试数据输出整形数列的最长递增子序列的长度,每个输出占一行。样例输入
样例输出
解题分析:本题数据量为100000,故允许的时间复杂度为O(nlog(n)),所以不能用动态规划来解题,所以,我们得根据最长递增子序列的性质来解题。有1 5 2 8 4 7 3 0 6 9 数字序列,我们另外开一个数组存储最长子序列,则首先有1,5进入数组,同时遇到数子2,我们知道相对一1-5,明显1-2组合更有利,更有利于后面的数子继续加入最长连续子序列,所以抛弃5,选择2,不断维持最佳序列,重复此操作,(1,2,8)、(1,2,4)、(1,2,4,7)、(1,2,3,7)、(0,2,3,7)、(0,2,3,6)、(0,2,3,6,9)。故最后长度为5,中间不断通过二分查找来更新值。
AC code :
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
int main (void){
int a;
int i;
while(scanf("%d",&a)!=EOF){
int length = 1;
int num[100005];
int ans[100005];
for(i=0;i<a;i++)
scanf("%d",&num[i]);
ans[0] = num[0];
for(i=1;i<a;i++){
int *pos;
//二分查找函数,查找大于或者等于查询值的下标
//只能用指针,否则编译错误
pos = lower_bound(ans,ans+length,num[i]);
if(pos - ans == length ) length++;
*pos = num[i];
}
printf("%d\n",length);
}
}
[/align]
[align=center]
[/align]
[align=center]Longest Ordered Subsequence[/align]
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 55194 | Accepted: 24749 |
A numeric sequence of
ai is ordered if a1 < a2 < ... <
aN. Let the subsequence of the given numeric sequence (a1,
a2, ..., aN) be any sequence (ai1,
ai2, ..., aiK), where 1 <=
i1 < i2 < ... < iK <=
N. For example, sequence (1, 7, 3, 5, 9, 4, 8) has ordered subsequences, e. g., (1, 7), (3, 4, 8) and many others. All longest ordered subsequences are of length 4, e. g., (1, 3, 5, 8).
Your program, when given the numeric sequence, must find the length of its longest ordered subsequence.
Input
The first line of input file contains the length of sequence N. The second line contains the elements of sequence - N integers in the range from 0 to 10000 each, separated by spaces. 1 <= N <= 1000
Output
Output file must contain a single integer - the length of the longest ordered subsequence of the given sequence.
Sample Input
7 1 7 3 5 9 4 8
Sample Output
4
题目描述:题意就是求一段数字序列中的最长递增序列
解题分析:首先,样例分析有数字序列sub[1005],由于本题最大数字的长度为1000,所以此题可以允许我们在O(n^2)的 时间复杂度,对于此题,我们首先推出递推式,我们首先创立一个数组 maxt[1005],a[0]代表第一个元素,a[1]代表到第二个元素的最长递增子序列,a[2]表示到第三个元素的最长递增子序列,a[3]表示到第四个元素的最长递增子序列······所以对于第
j个元素,对于它前面的元素可遍历,有遍历元素i,如果有 sub[ j ] >
sub[ i ],则有递推式:maxt[ j ] = max( maxt[ i ]+1 , maxt[ j ] ),
AC code:
#include<stdio.h> #include<cstring> #include<algorithm> #include<iostream> using namespace std; int main (void){ int a; int i,j; int sub[1005]; int maxt[1005],maxnumber=0; for(i=0;i<1005;i++) maxt[i] = 1; cin>>a; for(i=1;i<a+1;i++) cin>>sub[i]; for(i=2;i<a+1;i++) for(j=1;j<i;j++) if(sub[i] > sub[j]) maxt[i] = max( maxt[j]+1 , maxt[i]); for(i=1;i<=a;i++) if(maxnumber < maxt[i]) maxnumber = maxt[i]; printf("%d\n",maxnumber); }
南洋理工:214
单调递增子序列(二)
时间限制:1000 ms | 内存限制:65535 KB难度:4 描述:
给定一整型数列{a1,a2...,an}(0<n<=100000),找出单调递增最长子序列,并求出其长度。
如:1 9 10 5 11 2 13的最长单调递增子序列是1 9 10 11 13,长度为5。
输入:有多组测试数据(<=7)
每组测试数据的第一行是一个整数n表示序列中共有n个整数,随后的下一行里有n个整数,表示数列中的所有元素.每个整形数中间用空格间隔开(0<n<=100000)。
数据以EOF结束 。
输入数据保证合法(全为int型整数)!输出对于每组测试数据输出整形数列的最长递增子序列的长度,每个输出占一行。样例输入
7 1 9 10 5 11 2 13 2 2 -1
样例输出
5 1
解题分析:本题数据量为100000,故允许的时间复杂度为O(nlog(n)),所以不能用动态规划来解题,所以,我们得根据最长递增子序列的性质来解题。有1 5 2 8 4 7 3 0 6 9 数字序列,我们另外开一个数组存储最长子序列,则首先有1,5进入数组,同时遇到数子2,我们知道相对一1-5,明显1-2组合更有利,更有利于后面的数子继续加入最长连续子序列,所以抛弃5,选择2,不断维持最佳序列,重复此操作,(1,2,8)、(1,2,4)、(1,2,4,7)、(1,2,3,7)、(0,2,3,7)、(0,2,3,6)、(0,2,3,6,9)。故最后长度为5,中间不断通过二分查找来更新值。
AC code :
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
int main (void){
int a;
int i;
while(scanf("%d",&a)!=EOF){
int length = 1;
int num[100005];
int ans[100005];
for(i=0;i<a;i++)
scanf("%d",&num[i]);
ans[0] = num[0];
for(i=1;i<a;i++){
int *pos;
//二分查找函数,查找大于或者等于查询值的下标
//只能用指针,否则编译错误
pos = lower_bound(ans,ans+length,num[i]);
if(pos - ans == length ) length++;
*pos = num[i];
}
printf("%d\n",length);
}
}
相关文章推荐
- 最长递增子序列问题的求解
- 最长递增子序列长度问题
- 求一个数组的最长递增子序列(动态规划经典问题)
- 关于最长递增子序列问题的求解(LIS)
- 用O(nlog(n)实现最长递增子序列问题
- 最长递增子序列问题
- 最长递增子序列问题
- 关于最长递增子序列问题的求解(LIS)
- 线性规划与网络流24——最长递增子序列问题
- 最长递增子序列问题的求解
- 最长递增子序列和网易去除最少使从左向右递增又递减问题
- 最长递增子序列问题的求解
- 最长递增子序列问题的求解
- 最长递增子序列问题的求解(LIS)
- 最长递增子序列问题——动态规划
- 华为OJ训练题——最长递增子序列问题
- 最长递增子序列问题的求解
- 最长递增子序列问题 nyoj 17单调递增最长子序列 nyoj 79拦截导弹
- 最长递增子序列问题的求解
- 最长递增子序列(LIS)问题