O(nlogn)算法,最长上升子序列,,非动规

//最长上升子序列最快算法,非动态规划,运用了二分思想,还有栈的思想,
//用每一个数去和栈中的栈顶元素相比较,如果大于栈顶元素,则入栈,否则运用二分查找,寻找出第一个比这个数大的那个数替换
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cmath>
using namespace std;
int main()
{
    int temp, tail;
    int n;
    int stack[1001];
    scanf("%d", &n);
    tail = 0;
    stack[0] = -1;
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &temp);
        if (temp > stack[tail])
            stack[++tail] = temp;//入栈
        else {
            int l = 1, r = tail;
            int  mid;
            while (l <= r)//二分
            {
                mid = (l + r) / 2;
                if (temp > stack[mid])
                    l = mid + 1;
                else r = mid - 1;
            }
            stack[l] = temp;
        }
    }
    printf("%d", tail);
    return 0;
}
时间: 2024-10-13 18:43:38

O(nlogn)算法,最长上升子序列,,非动规的相关文章

LCS(最长公共子序列)动规算法正确性证明

今天在看代码源文件求diff的原理的时候看到了LCS算法.这个算法应该不陌生,动规的经典算法.具体算法做啥了我就不说了,不知道的可以直接看<算法导论>动态规划那一章.既然看到了就想回忆下,当想到算法正确性的时候,发现这个算法的正确性证明并不好做.于是想了一段时间,里面有几个细节很trick,容易陷进去.想了几轮,现在把证明贴出来,有异议的可以留言一起交流. 先把一些符号和约定说明下: 假设有两个数组,A和B.A[i]为A的第i个元素,A(i)为有A的第一个元素到第i个元素所组成的前缀.m(i,

HDU-1025 Constructing Roads In JGShining&#39;s Kingdom O(nlogn)的最长上升子序列

模板题,唯一问题是当长度为1是,road是单数,不然road是复数roads. #include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <queue> #include <vector> #include <cstdlib> #include <algorithm> using namespace st

跟着编程之美学算法——最长公共子序列

最长公共子序列是一个很经典的动态规划问题,最近正在学习动态规划,所以拿来这里再整理一下. 这个问题在<算法导论>中作为讲动态规划算法的例题出现. 动态规划,众所周知,第一步就是找子问题,也就是把一个大的问题分解成子问题.这里我们设两个字符串A.B,A = "a0, a1, a2, ..., am-1",B = "b0, b1, b2, ..., bn-1". (1)如果am-1 == bn-1,则当前最长公共子序列为"a0, a1, ...,

编程算法 - 最长公共子序列(LCS) 代码(C)

最长公共子序列(LCS) 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 给定两个字符串s,t, 求出这两个字符串最长的公共子序列的长度. 字符串的子序列并一定要连续, 能够包含间隔. 即最长公共子序列问题(LCS, Longest Common Subsequence) 使用动态规划, 假设字符相等, 两个字符串就依次递增一位, 一直到字符串的结尾. 代码: /* * main.cpp * * Created on: 2014.7.17

[ACM] hdu 1231 最大连续子序列 (动规复习)

最大连续子序列 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 17687    Accepted Submission(s): 7828 Problem Description 给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ..., Nj },其中 1 <= i <= j

nlogn 求最长上升子序列 LIS

最近在做单调队列,发现了最长上升子序列O(nlogn)的求法也有利用单调队列的思想. 最长递增子序列问题:在一列数中寻找一些数,这些数满足:任意两个数a[i]和a[j],若i<j,必有a[i]<a[j],这样最长的子序列称为最长递增子序列. 设dp[i]表示以i为结尾的最长递增子序列的长度,则状态转移方程为: dp[i] = max{dp[j]+1}, 1<=j<i,a[j]<a[i]. 这样简单的复杂度为O(n^2),其实还有更好的方法. 考虑两个数a[x]和a[y],x&

编程算法 - 最长上升子序列问题 代码(C)

最长上升子序列问题 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 有一个长为n的数列a. 请求出这个序列中最长上升子序列的长度. 最长上升子序列的数字之间可以有间隔. 即最长上升子序列(LIS, Longest Increasing Subsequence), 例如: n=5, a={4,2,3,1,5}, result=3(2,3,5). 使用动态规划求解(DP). 方法1: 依次求出每个数字之前的最长上升子序列, 时间复杂度O(n^2

HDU4604.Deque——nlogn求最长上升子序列的长度

http://acm.hdu.edu.cn/showproblem.php?pid=4604 把一个序列中的元素放到队列里面,有3种操作,对于第i个元素 1.放到队头2.放到队尾3.舍弃 求最长上升序列的长度 法1:求出每个以a[i]为起点的最长不升子序列的长度,和最长不降子序列的长度,两个相加再减去a[i]重复的次数 法2:把当前序列复制两个,一个逆序,求总共的最长上升子序列的长度,然后奇偶避免重复 //法1 #include <iostream> #include <cstring&

O(nlogn)的最长上升子序列并且记录所选择的数 模板

#include <iostream> #include <cstdlib> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> using namespace std; const int MAXN = 10000 + 10; int A[MAXN]; int lis[MAXN]; int f[MAXN]; int stack[MAXN