动态规划——E (LIS())最长上升子序列

E - LIS

Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

Submit Status

Description

The world financial crisis is quite a subject. Some people are more relaxed while others are quite anxious. John is one of them. He is very concerned about the evolution of the stock exchange. He follows stock prices every day looking for rising trends. Given a sequence of numbers p1, p2,...,pn representing stock prices, a rising trend is a subsequence pi1 < pi2 < ... < pik, with i1 < i2 < ... < ik. John’s problem is to find very quickly the longest rising trend.

Input

Each data set in the file stands for a particular set of stock prices. A data set starts with the length L (L ≤ 100000) of the sequence of numbers, followed by the numbers (a number fits a long integer). 
White spaces can occur freely in the input. The input data are correct and terminate with an end of file.

Output

The program prints the length of the longest rising trend. 
For each set of data the program prints the result to the standard output from the beginning of a line.

Sample Input

6
5 2 1 4 5 3
3
1 1 1
4
4 3 2 1

Sample Output

3
1
1

Hint

There are three data sets. In the first case, the length L of the sequence is 6. The sequence is 5, 2, 1, 4, 5, 3. The result for the data set is the length of the longest rising trend: 3.

解题思路:这个题目是一个求最长递增子序列问题,找一个数组存输入的最大升序,然后它的长度就是我们需要输出的答案需,要用二分忧化法做,

我们的问题是要如何找到最大升序数组?这里可以分成两步:1.判断当前数字时候大于前一数字,若是:把它放在数组后面,否则:通过2分法,判断它的大小应该放的位置即可。

程序代码:

#include <cstdio>
using namespace std;
const int L=100010;
int a[L],b[L];
int n;
void init()
{
    for(int i=0;i<n;i++)
        scanf("%d",&a[i]);
}
int  bin(int r,int k)
{
    int l=1;
    while(l<=r)
       {
        int mid=(l+r)/2;
        if(k>b[mid])
            l=mid+1;
        else
            r=mid-1;
       }
    return l;
}
int  work()
{
    int i,j,k;
    int c=0;
    for(i=0;i<n;i++)
    if(c==0||a[i]>b[c])
        b[++c]=a[i];
    else
    {
        k=bin(c,a[i]);
        b[k]=a[i];
    }
    return c;
}
int main()
{
     while(scanf("%d",&n)==1)
    {
       init();
       printf("%d\n",work());
    }
    return 0;
}

时间: 2024-10-19 23:59:26

动态规划——E (LIS())最长上升子序列的相关文章

动态规划模板1|LIS最长上升子序列

LIS最长上升子序列 dp[i]保存的是当前到下标为止的最长上升子序列的长度. 模板代码: int dp[MAX_N], a[MAX_N], n; int ans = 0; // 保存最大值 for (int i = 1; i <= n; ++i) { dp[i] = 1; for (int j = 1; j < i; ++j) { if (a[j] < a[i]) { dp[i] = max(dp[i], dp[j] + 1); } } ans = max(ans, dp[i]); }

算法设计 - LCS 最长公共子序列&amp;&amp;最长公共子串 &amp;&amp;LIS 最长递增子序列

出处 http://segmentfault.com/blog/exploring/ 本章讲解:1. LCS(最长公共子序列)O(n^2)的时间复杂度,O(n^2)的空间复杂度:2. 与之类似但不同的最长公共子串方法.最长公共子串用动态规划可实现O(n^2)的时间复杂度,O(n^2)的空间复杂度:还可以进一步优化,用后缀数组的方法优化成线性时间O(nlogn):空间也可以用其他方法优化成线性.3.LIS(最长递增序列)DP方法可实现O(n^2)的时间复杂度,进一步优化最佳可达到O(nlogn)

hdu 5256 序列变换(LIS最长上升子序列)

Problem Description 我们有一个数列A1,A2...An,你现在要求修改数量最少的元素,使得这个数列严格递增.其中无论是修改前还是修改后,每个元素都必须是整数. 请输出最少需要修改多少个元素. Input 第一行输入一个T(1≤T≤10),表示有多少组数据 每一组数据: 第一行输入一个N(1≤N≤105),表示数列的长度 第二行输入N个数A1,A2,...,An. 每一个数列中的元素都是正整数而且不超过106. Output 对于每组数据,先输出一行 Case #i: 然后输出

POJ 1887 Testingthe CATCHER (LIS:最长下降子序列)

POJ 1887Testingthe CATCHER (LIS:最长下降子序列) http://poj.org/problem?id=3903 题意: 给你一个长度为n (n<=200000) 的数字序列, 要你求该序列中的最长(严格)下降子序列的长度. 分析:        读取全部输入, 将原始数组逆向, 然后求最长严格上升子序列就可以. 因为n的规模达到20W, 所以仅仅能用O(nlogn)的算法求.        令g[i]==x表示当前遍历到的长度为i的全部最长上升子序列中的最小序列末

POJ - 3903 Stock Exchange(LIS最长上升子序列问题)

E - LIS Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Description The world financial crisis is quite a subject. Some people are more relaxed while others are quite anxious. John is one of them. He is very concerned abo

lis(最长上升子序列) dp

lis(最长上升子序列) dp 求序列的lis,子序列可不连续 for(int i=1;i<=N;i++){ scanf("%d",&a[i]); dp[i]=1; } for(int i=2;i<=N;i++){ for(int j=1;j<i;j++){ if(a[j]<a[i]) dp[i]=max(dp[i],dp[j]+1); } } int ans=1; for(int i=1;i<=N;i++){ //注意并不是dp[N]最大,而是要

poj2533——lis(最长上升子序列), 线性dp

poj2533——lis(最长上升子序列), 线性dp Longest Ordered Subsequence Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 36143   Accepted: 15876 Description A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence of the given n

hdu 5421 小明系列问题——小明序列(LIS最长上升子序列)

1 /***************************************************** 2 题目: 小明系列问题——小明序列(hdu 4521) 3 链接: http://acm.hdu.edu.cn/showproblem.php?pid=4521 4 算法: LIS最长上升子序列 5 6 ******************************************************/ 7 #include<cstdio> 8 #include<

POJ 3903 Stock Exchange (LIS:最长上升子序列)

POJ 3903Stock Exchange (LIS:最长上升子序列) http://poj.org/problem?id=3903 题意: 给你一个长度为n (n<=100000) 的数字序列, 要你求该序列中的最长(严格)上升子序列的长度. 分析: 由于n的规模达到10W, 所以只能用O(nlogn)的算法求. 令g[i]==x表示当前遍历到的长度为i的所有最长上升子序列中的最小序列末尾值为x.(如果到目前为止, 根本不存在长i的上升序列, 那么x==INF无穷大) 假设当前遍历到了第j个