http://wikioi.com/problem/1576/

经典的动态规划。我写了个o(n^2)的DP方法。

PPT:http://wenku.baidu.com/view/bd290294dd88d0d233d46ac7.html

线型动态规划问题,最典型的特征就是状态都在一条线上,并且位置固定,问题一般都规定只能从前往后取状态,解决的办法是根据前面的状态特征,选取最优状态作为决策进行转移。
设前i个点的最优值,研究前i-1个点与前i个点的最优值,
利用第i个点决策转移,如下图。
状态转移方程一般可写成:
fi(k) = min{ fi-1 or j( k’) + u(i,j) or u(i,i-1) }

#include <iostream>
using namespace std;
int arr[5000+10];
int inc[5000+10];
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
// assume n >= 1
inc[0] = 1;
for (int i = 1; i < n; i++)
{
int max = 0;
for (int j = i-1; j >= 0; j--)
{
if (arr[i] > arr[j] && inc[j] > max) max = inc[j];
}
inc[i] = max + 1;
}
cout << inc[n-1];
return 0;
}

但其实还有个o(nlogn)的方法。因为优化DP有两种方法,一种就是优化状态数,比如棋盘型有时能把四维优化成三维;一种就是优化转移步骤,这里可以把转移步骤的复杂度由n优化成log n。

一种是采用线段树的数据结构,那么从左像右扫,一边扫一边更新区间的最值,然后也查询之前的最值,由于线段树的操作都收log n的,所以最终n*logn

第二种就是采用单调序列的数据结构,其操作如下:

开辟一个栈b,每次取栈顶元素s和读到的元素a做比较,如果a>s,则置为栈顶;如果a<s,则二分查找栈中的比a大的第1个数,并替换。最终栈的大小即为最长递增子序列为长度
考察b栈内每个元素的含义,b[i] 表示所有长度为i的上升子序列中最小的最后一个数.
·举例:原序列为3,4,5,2,4,2
栈为3,4,5,此时读到2,则用2替换3,得到栈中元素为2,4,5,再读4,用4替换5,得到2,4,4,再读2,得到最终栈为2,2,4,最终得到的解是:
长度为1的上升子序列中最小的最后一个数是2 (2)
长度为2的上升子序列中最小的最后一个数是2 (2,2)长度为3的上升子序列中最小的最后一个数是4 (3,4,4)
可知没有长度为4的上升子序列,最长递增子序列长度为3. (3,4,4)

参见:http://www.slyar.com/blog/longest-ordered-subsequence.html

这也是很好理解的,对于x和y,如果x < y且Stack[y] < Stack[x],用Stack[x]替换Stack[y],此时的最长序列长度没有改变但序列Q的''潜力''增大了。

单调序列这里还有一个简单应用,可以练习一下:http://poj.org/problem?id=2823

[wikioi]最长严格上升子序列的更多相关文章

  1. wikioi 1576 最长严格上升子序列

    简单的最长严格上升子序列的题 dp[i]表示到a[i]这个数为最后的时候最大的长度是多少 然后就差不多了吧~ #include <cstdio> #include <cmath> ...

  2. lintcode 最长上升连续子序列 II(二维最长上升连续序列)

    题目链接:http://www.lintcode.com/zh-cn/problem/longest-increasing-continuous-subsequence-ii/ 最长上升连续子序列 I ...

  3. 最长公共上升子序列(codevs 2185)

    题目描述 Description 熊大妈的奶牛在小沐沐的熏陶下开始研究信息题目.小沐沐先让奶牛研究了最长上升子序列,再让他们研究了最长公共子序列,现在又让他们要研究最长公共上升子序列了. 小沐沐说,对 ...

  4. 最长公共上升子序列(LCIS)

    最长公共上升子序列慕名而知是两个字符串a,b的最长公共递增序列,不一定非得是连续的.刚开始看到的时候想的是先用求最长公共子序列,然后再从其中找到最长递增子序列,可是仔细想一想觉得这样有点不妥,然后从网 ...

  5. 最长不下降子序列(LIS)

    最长上升子序列.最长不下降子序列,解法差不多,就一点等于不等于的差别,我这里说最长不下降子序列的. 有两种解法. 一种是DP,很容易想到,就这样: REP(i,n) { f[i]=; FOR(j,,i ...

  6. 最长不下降子序列 O(nlogn) || 记忆化搜索

    #include<stdio.h> ] , temp[] ; int n , top ; int binary_search (int x) { ; int last = top ; in ...

  7. tyvj 1049 最长不下降子序列 n^2/nlogn

    P1049 最长不下降子序列 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 求最长不下降子序列的长度 输入格式 第一行为n,表示n个数第二行n个数 输出格式 ...

  8. 最长不下降子序列的O(n^2)算法和O(nlogn)算法

    一.简单的O(n^2)的算法 很容易想到用动态规划做.设lis[]用于保存第1~i元素元素中最长不下降序列的长度,则lis[i]=max(lis[j])+1,且num[i]>num[j],i&g ...

  9. 最长不下降子序列//序列dp

    最长不下降子序列 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 求最长不下降子序列的长度 输入格式 第一行为n,表示n个数第二行n个数 输出格式 最长不下降 ...

随机推荐

  1. JVM工作原理和特点

    操作系统装入JVM,是通过jdk中的java.exe来完成,通过以下4个步骤: 1. 创建JVM装载环境和配置: JVM装入系统,JVM提供的方式是操作系统的动态链接文件.文件就是一个装入路径的问题, ...

  2. 骑士飞行棋 C#代码详解

    最近看见一个骑士飞行棋的小游戏代码,感觉这个代码中将大多数C#的基础知识都运用到了,是一个新手检验学习成果的有效方法,特此将这个代码整理一遍.这是一个控制台程序.这是代码下载地址,代码中的注释非常详细 ...

  3. java反射技术

    Class c2 = Class.forName("com.reflection.Test"); // 对类的寻找,找到一个类,注意不是对象 WifiManager mWifiMa ...

  4. JDBC——架构层、驱动

    JDBC(java Datebase Connector) jdbc驱动程序 四种类型: jdbc-odbc桥接驱动程序 Native-API JDBC-Net Native-Protocol (常见 ...

  5. 安装oracle pl/sql developer

    1.在官网上下载oracle 11g R2版本的数据库,直接常规安装.数据库可以下载32bit. 2.在这里下载oracle client (32bit)http://www.oracle.com/t ...

  6. CSS3中的transform

    CSS3 转换,我们能够对元素进行移动.缩放.转动.拉长或拉伸. transform 在2D里主要是4个方法.除了rotate 其他都是接受x y值 translate skew rotate sca ...

  7. Java工具类:获取long型唯一ID

    直接上代码: import java.text.SimpleDateFormat; import java.util.Date; /** * 获取long型唯一ID */ public class I ...

  8. java中运算符——进度1

    Class Demo1{    public static void main(String[] args) {        /*        一.逻辑运算法用于连接两个boolean类型的表达式 ...

  9. 使用Map辅助拼装树状结构,消除递归调用

    目前菜单或其他树状结构在数据库中的存储,多数是以一个parentid作为关联字段,以一维形式存储.使用时全部查询出来,然后在内存中拼装成树状结构.现在主要涉及的是拼装方法的问题. 一般可以进行 递归调 ...

  10. shell脚本修复MySQL主从同步

    发布:thebaby   来源:net     [大 中 小] 分享一例shell脚本,用于修改mysql的主从同步问题,有需要的朋友参考下吧. 一个可以修改mysql主从同步的shell脚本. 例子 ...