LIS教学篇

LIS是最长上升子序列,(递增子序列是指,子序列的元素是递增的)例如:5 1 6 8 2 4 5 10,最长递增子序列是1 2 4 5 10。

对于LIS,有两种解法,一种是比较容易想到的O(n^2)的解法,我们用N[i]表示第i个数,dp[i]表示第i个数所在子序列中最大的长度(比如对于序列{1,2,5,4,2},那dp={1,2,3,3,2}).那么我们只要枚举j从1到i-1,且N[j]<N[i],就可以进行更新:dp[i]=min(dp[i],dp[j]+1),这样的复杂度是O(n^2)。

O(n^2)的复杂度往往是不如人意的,我们可以考虑尝试优化,如果我们用dp[i]表示长度为i的子序列的最后一个数的最小值,那么我们可以发现这样的dp数组一定是非递减的,因为如果长度为2的子序列末尾最小值是3,那长度为1的子序列末尾最小值肯定可以取3,是不可能小于3的,因此我们可以先把数组初始化为INF,每次更新的时候二分一下dp数组,找到一个大于等于N[i]的数的位置,然后在这个地方更新。举个例子,对于

5 1 6 8 2 4 5 10这个序列

一开始dp数组为:

INF INF INF INF INF INF INF INF

更新5的时候,在1的位置(下标从1开始)更新,表示长度为1的子序列的最后一个数最小是5,此时dp数组为

5 INF INF INF INF INF INF INF

更新1的时候,二分到1的位置,在1的位置更新,表示长度为1的子序列的最后一个数最小是1,此时dp数组为

1 INF INF INF INF INF INF INF

更新6的时候,二分到2的位置,在2的位置更新,表示长度为2的子序列的最后一个数最小是6,此时dp数组为

1 6 INF INF INF INF INF INF

更新8的时候,二分到3的位置,在3的位置更新,表示长度为3的子序列的最后一个数最小是8,此时dp数组为

1 6 8 INF INF INF INF INF

更新2的时候,二分到2的位置,在2的位置更新,表示长度为2的子序列的最后一个数最小是2,此时dp数组为

1 2 8 INF INF INF INF INF

更新4的时候,二分到3的位置,在3的位置更新,表示长度为3的子序列的最后一个数最小是4,此时dp数组为

1 2 4 INF INF INF INF INF

更新5的时候,二分到4的位置,在4的位置更新,表示长度为4的子序列的最后一个数最小是5,此时dp数组为

1 2 4 5 INF INF INF INF

更新10的时候,二分到5的位置,在5的位置更新,表示长度为5的子序列的最后一个数最小是10,此时dp数组为

1 2 4 5 10 INF INF INF

这时候dp数组处理完毕,5为LIS长度。

可以在这里测试下代码:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1134

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#define X first
#define Y second
#define clr(u,v); memset(u,v,sizeof(u));
#define in() freopen("data","r",stdin);
#define out() freopen("ans","w",stdout);
#define Clear(Q); while (!Q.empty()) Q.pop();
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int maxn = 1e5 + 10;
const int INF = 0x3f3f3f3f;
int c[maxn];//c[i]代表序列长度为i时的最小数字
int main()
{
    int n, x;
    scanf("%d", &n);
    clr(c, 0x3f);//一开始全部初始化为INF
    for (int i = 0; i < n; i++)
    {
        scanf("%d", &x);
        int pos = lower_bound(c + 1, c + 1 + n, x) - c;//找到c中第一个大于等于x的数字的下标
//        for (int j = 1; j <= n; j++)
//            printf("%d ", c[j]);
//        puts("");
//        printf("pos : %d\n", pos);
        c[pos] = min(c[pos], x);
    }
    printf("%d\n", lower_bound(c + 1, c + 1 + n, INF) - (c + 1));
    return 0;
}
时间: 2024-10-17 21:52:39

LIS教学篇的相关文章

大快搜索数据爬虫技术实例安装教学篇

大快搜索数据爬虫技术实例安装教学篇 爬虫安装前准备工作:大快大数据平台安装完成.zookeeper.redis.elasticsearch.mysql等组件安装启动成功. 1.修改爬虫安装配置文件(最好在线下修改好后再上传平台) 2.修改crawler\dkcrw\jdbc.properties配置文件(只修改图片里的内容其他内容默认即可) Hbase.zookeeper.quorum所填地址应在DKM监控平台查看: Redis相关配置看如下界面: 3.把已修改的crawler\dkcrw\下的

Git 的核心概念解读

本文不是Git使用教学篇,而是偏向理论方面,旨在更加深刻的理解Git,这样才能更好的使用它,让工具成为我们得力的助手. 版本控制系统 Git 是目前世界上最优秀的分布式版本控制系统.版本控制系统是能够随着时间的推进记录一系列文件的变化以便于你以后想要的退回到某个版本的系统.版本控制系统分为三大类:本地版本控制系统,集中式版本控制系统和分布式版本控制系统 本地版本控制(Local Version Control Systems)是将文件的各个版本以一定的数据格式存储在本地的磁盘(有的VCS 是保存

Nginx + Tomcat 动静分离实现负载均衡

0.前期准备 使用Debian环境.安装Nginx(默认安装),一个web项目,安装tomcat(默认安装)等. 1.一份Nginx.conf配置文件 # 定义Nginx运行的用户 和 用户组 如果对应服务器暴露在外面的话建议使用权限较小的用户 防止被入侵 # user www www; #Nginx进程数, 建议设置为等于CPU总核心数 worker_processes 8; #开启全局错误日志类型 error_log /var/log/nginx/error.log info; #进程文件

树莓派玩耍笔记2 -- 我的板子是正品么?(解答一些小问题)

由于我的树莓派是在某宝买的,跟很多人一样,在某宝买东西,你肯定害怕自己买的东西会不会是仿制品或者是阉割版.同样,强大的中国代工厂会不会自己对树莓派进行修改或者是照抄后发布在淘宝上?所以我历经千辛万苦寻找各种资料查看我的板子是不是正品. 1. 国产红板和绿板的标准配置 爱板网大神"ukonline2000" 发布了两篇帖子<爱板首发-国产红派评测-外观开箱篇!!!>,<爱板首发-国产红派评测-性能测试教学篇!!!>.我们可以看出,红板和绿板中还是有部分芯片都是不一

OpenDaylight 2015峰会,What are you弄啥咧?

OpenDaylight现在到底发展如何?研究这个有没有前途?现在研究OpenDaylight还来得及吗?这或许是很多人会关注的问题.不过与其纠结这个问题,倒不如看看第二届的OpenDaylight峰会到底整了些啥,或许会让你对OpenDaylight的发展有个更加立体的认识.根据官方的说法这次峰会旨在为创新者.开发者.软件定义网络(SDN)和网络功能虚拟化(NFV)用户提供协作和教育场地.该峰会聚集了推动SDN和NFV生态系统发展的社区.项目.产品和网络行业公司,以及来自世界传统开源的最好实践

零元学Expression Blend 4 - Chapter 14 用实例了解布局容器系列-「Pathlistbox」II

原文:零元学Expression Blend 4 - Chapter 14 用实例了解布局容器系列-「Pathlistbox」II 本章将延续上一章的范例,步骤解析. 本章将延续上一章的范例,步骤解析. 若是对Pathlistbox基本属性还不认识的朋友,请返回上一章,小猴子良心建议:先求精.再求广! 01 开启一个新专案後,在主要工作区放入一个Ellipse,并调整到适当的位置 接着,建立我们的文字「I Love Blend 4」 这边要注意的一点: 若要做出范例的排列方式,每个字元必独立在自

Git 的核心概念

本文不是Git使用教学篇,而是偏向理论方面,旨在更加深刻的理解Git,这样才能更好的使用它,让工具成为我们得力的助手. 版本控制系统 Git 是目前世界上最优秀的分布式版本控制系统.版本控制系统是能够随着时间的推进记录一系列文件的变化以便于你以后想要的退回到某个版本的系统.版本控制系统分为三大类:本地版本控制系统,集中式版本控制系统和分布式版本控制系统 本地版本控制(Local Version Control Systems)是将文件的各个版本以一定的数据格式存储在本地的磁盘(有的VCS 是保存

负载均衡 | Nginx+Tomcat 动静分离实现负载均衡

0.前期准备 使用Debian环境.安装Nginx(默认安装),一个web项目,安装tomcat(默认安装)等. 1.一份Nginx.conf配置文件 基本配置这个文件,就可以实现负载了.但是里面的各种关系要了解就比较麻烦了.这篇博客,也不是教学篇,是记录一下,方便以后自己看了. 2.基础讲解 现在假使有一台电脑192.168.8.203这台电脑,上面部署了Tomcat,里面8080端口有J2EE的服务,通过浏览器可以正常浏览网页.现在有一个问题tomcat是一个比较全面的web容器,对静态网页

诗经 全文

诗经 全文 (带注释和译文) http://www.edu009.com/Article/HTML/Article_60756.html <诗经> 春秋·孔丘 <诗经>是我国第一部诗歌总集,先秦时代称为“诗”或“诗三百”,孔子加以了整理.汉武帝采纳董仲舒“罢黜百家,独尊儒术”的建议,尊“诗”为经典,定名为<诗经>. <诗经>现存诗歌 305 篇,包括西周初年到春秋中叶共 500 余年的民歌和朝庙乐章,分为风.雅.颂三章. “风”包括周南.召南.邶.鄘.卫.王