动规(LIS)-POJ-2533

http://poj.org/problem?id=2533

Longest Ordered Subsequence

给定n个正整数,求最长上升子序列(LIS)长度(子序列中的元素不要求连续).

解题报告

思路

经典的LIS问题,O(n^2)的朴素做法不多作介绍,仅仅介绍O(n logn)的做法。

对于n个元素的数组array,建立一个数组d[n]。

其中d[i]表示长度为i的子序列中最小的末尾元素为d[i]。

数组d显然是升序的,可用反证法证明:

假设存在d[i]>=d[j]且i<j。

那么由于i<j,那么在d[j]结尾的子序列中,必然存在某个值array[k]<d[j]<=d[i],使得以array[k]结尾的LIS长度为i,因而与假设矛盾。

根据d数组的升序性质,可以循环遍历array数组:

对于遍历到的array[i],在d数组中二分查找最后一个小于array[i]的元素d[k],那么以array[i]结尾的LIS的长度则为k+1。同时更新d数组。

那么时间复杂度就为O(n logn)

代码

#include <algorithm>
#include <cstring>
#include <iostream>

using namespace std;

const int maxn = 1003;
const int INF = 0x3f3f3f3f;

int minNum[maxn];
int n;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    while (cin >> n) {
        memset(minNum, INF, sizeof(minNum));
        minNum[0] = -1;

        int num, len, ans = 1;
        for (int i = 0; i < n; i++) {
            cin >> num;
            len = lower_bound(minNum, minNum + n, num) - minNum;
            if(minNum[len] == num) len--;
            minNum[len] = min(minNum[len], num);
            ans = max(ans, len);
        }

        cout << ans << endl;
    }

    return 0;
}
时间: 2024-10-06 16:01:33

动规(LIS)-POJ-2533的相关文章

POJ 2955 Brackets (动规)

Brackets Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2999   Accepted: 1536 Description We give the following inductive definition of a "regular brackets" sequence: the empty sequence is a regular brackets sequence, if s is a reg

poj 3903 &amp; poj 2533 最长上升子序列(LIS)

最长上升子序列. 做这道题之前先做了2533,再看这道题,感觉两道题就一模一样,于是用2533的代码直接交, TLE了: 回头一看,数据范围.2533 N:0~1000:3903 N :1~100000. 原因终归于算法时间复杂度. 也借这道题学习了nlgn的最长上升子序列.(学习链接:http://blog.csdn.net/dangwenliang/article/details/5728363) 下面简单介绍n^2 和 nlgn 的两种算法. n^2: 主要思想:DP: 假设A1,A2..

poj 2533 &amp; poj 1631 Longest Ordered Subsequence( LIS果题 )

题目链接: POJ 2533:http://poj.org/problem?id=2533 POJ 1631:http://poj.org/problem?id=1631 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,

POJ 2533 Longest Ordered Subsequence(LIS模版题)

Longest Ordered Subsequence Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 47465   Accepted: 21120 Description A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence of the given numeric sequence (a1, a2, ...

(动规 或 最短路)Help Jimmy(poj 1661)

http://poj.org/problem?id=1661 Description "Help Jimmy" 是在下图所示的场景上完成的游戏. 场景中包括多个长度和高度各不相同的平台.地面是最低的平台,高度为零,长度无限. Jimmy老鼠在时刻0从高于所有平台的某处开始下落,它的下落速度始终为1米/秒.当Jimmy落到某个平台上时,游戏者选择让它向左还是向右跑,它跑动的速度也是1米/秒.当Jimmy跑到平台的边缘时,开始继续下落.Jimmy每次下落的高度不能超过MAX米,不然就会摔死

POJ 1088 滑雪 (动规)

滑雪 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 75664 Accepted: 28044 Description Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道载一个区域中最长底滑坡.区域由一个二维数组给出.数组的每个数字代表点的高度.下面是一个例子 1 2 3 4 5 16 17 18 1

[kuangbin带你飞]专题十二 基础DP1 N - Longest Ordered Subsequence POJ - 2533(最长上升子序列LIS)

N - Longest Ordered Subsequence POJ - 2533 题目链接:https://vjudge.net/contest/68966#problem/N 题目: 最长有序子序列如果a1 <a2 <... <aN,则排序ai的数字序列. 让给定数字序列(a1,a2,...,aN)的子序列为任何序列(ai1,ai2,...,aiK),其中1 <= i1 <i2 <... <iK <= N 例如,序列(1,7,3,5,9,4,8)具有有

动规,模拟,递推,最长公共子序列

题目链接:http://poj.org/problem?id=1458 解题报告: 1.用二维数组模拟两个字符串上每个子串对应的最长公共子序列. 2.显然,就是要求二维数组最右下的数字 3.递推公式: if(s1[i-1]==s2[j-1]) maxlen[i][j]=maxlen[i-1][j-1]+1; else maxlen[i][j]=max(maxlen[i][j-1],maxlen[i-1][j]); Memory: 1024KTime: 0MSLanguage: C++Result

动规之区间动规小结

区间动规主要有两种方法: 一.是先想出递归式,然后将之转化为滚动数组. 二.或者从小区间贪到大区间. POJ  1159  点击打开链接 AC代码如下: #include<iostream> #include<cstring> #include<algorithm> using namespace std; char a[5005]; short dp[5005][5005]; int min(int a,int b) { return a<b?a:b; } in