题目地址:http://ac.jobdu.com/problem.php?pid=1533

题目描述:

给定一个整型数组, 求这个数组的最长严格递增子序列的长度。 譬如序列1 2 2 4 3 的最长严格递增子序列为1,2,4或1,2,3.他们的长度为3。

输入:

输入可能包含多个测试案例。
对于每个测试案例,输入的第一行为一个整数n(1<=n<=100000):代表将要输入的序列长度
输入的第二行包括n个整数,代表这个数组中的数字。整数均在int范围内。

输出:

对于每个测试案例,输出其最长严格递增子序列长度。

样例输入:
4
4 2 1 3
5
1 1 1 1 1
样例输出:
2
1

参考《编程之美》2.16

对于前面i个元素的任何一个递增子序列,如果这个子序列的最大的元素比array[i+1]小,那么就可以将array[i+1]加在这个子序列后面,构成一个新的子序列。

比如当i=4的时候,目标序列为:1,-1,2,-3,4,-5,6,-7最长递增序列为:(1, 2),(-1, 2)。那么,只要4>2,就可以把4直接增加到前面的子序列中形成一个新的递增子序列。

因此,我们希望找到前i个元素的一个递增子序列,使得这个递增子序列的最大元素比array[i+1]小,且长度尽量地大。这样将array[i+1]加在该递增子序列后,便可找到以array[i+1]为最大元素的最长递增子序列。

仍然假设在数组的前i个元素中,以array[i]为最大元素的最长递增子序列的长度为LIS[i]。

同时,假设:

长度为1的递增子序列最大元素的最小值为MaxV[1];

长度为2的递增子序列最大元素的最小值为MaxV[2];

……

长度为LIS[i]的递增子序列最大元素的最小值为MaxV[LIS[i]]。

具体算法实现如下:

#include <stdio.h>

#define MAX 100000
#define VMAX 100001
#define MIN (-2147483647 - 1) int BSearch (int MaxV[], int start, int end, int key){
int mid; while (start <= end){
mid = start + ((end - start) >> 1);
if (MaxV[mid] < key){
start = mid + 1;
}
else if (MaxV[mid] > key){
end = mid - 1;
}
else
return mid;
}
return start;
} int LIS (int data[], int n){
int MaxV[VMAX];
MaxV[1] = data[0];
MaxV[0] = MIN;
int LIS[MAX]; int nMaxLIS = 1;
int i, j;
for (i=0; i<n; ++i)
LIS[i] = 1;
for (i=1; i<n; ++i){
j = BSearch (MaxV, 0, nMaxLIS, data[i]) - 1;
LIS[i] = j + 1;
if (LIS[i] > nMaxLIS){
nMaxLIS = LIS[i];
MaxV[LIS[i]] = data[i];
}
else if (MaxV[j] < data[i] && data[i] < MaxV[j + 1]){
MaxV[j+1] = data[i];
}
}
return nMaxLIS;
} int main(void){
int data[MAX];
int n;
int i; while (scanf ("%d", &n) != EOF){
for (i=0; i<n; ++i){
scanf ("%d", &data[i]);
}
printf ("%d\n", LIS (data, n));
} return 0;
}

根据参考资料可以知道完全不需要LIS[i]数组去定位,直接用MaxV[i]的下标作为LIS的长度即可。

代码更改如下:

#include <stdio.h>

#define MAX 100000
#define VMAX 100001
#define MIN (-2147483647 - 1) int BSearch (int MaxV[], int start, int end, int key){
int mid; while (start <= end){
mid = start + ((end - start) >> 1);
if (MaxV[mid] < key){
start = mid + 1;
}
else if (MaxV[mid] > key){
end = mid - 1;
}
else
return mid;
}
return start;
} int LIS (int data[], int n){
int MaxV[VMAX];
MaxV[1] = data[0];
MaxV[0] = MIN; int nMaxLIS = 1;
int i, j;
for (i=1; i<n; ++i){
j = BSearch (MaxV, 0, nMaxLIS, data[i]);
if (j > nMaxLIS){
nMaxLIS = j;
MaxV[j] = data[i];
}
else if (MaxV[j-1] < data[i] && data[i] < MaxV[j]){
MaxV[j] = data[i];
}
}
return nMaxLIS;
} int main(void){
int data[MAX];
int n;
int i; while (scanf ("%d", &n) != EOF){
for (i=0; i<n; ++i){
scanf ("%d", &data[i]);
}
printf ("%d\n", LIS (data, n));
} return 0;
}

HDOJ上相似的题目:1025 -- Constructing Roads In JGShining's Kingdom

参考资料:http://www.ahathinking.com/archives/117.html

九度OJ 1533 最长上升子序列 -- 动态规划的更多相关文章

  1. 九度oj 1530 最长不重复子串

    原题链接:http://ac.jobdu.com/problem.php?pid=1530 字符串简单题,看似O(n^2)的复杂度10000的数据量会tle,其实最长不重复子串不超过26个嘛... 如 ...

  2. 九度OJ 1528 最长回文子串 -- Manacher算法

    题目地址:http://ac.jobdu.com/problem.php?pid=1528 题目描述: 回文串就是一个正读和反读都一样的字符串,比如"level"或者"n ...

  3. 九度OJ 1011:最大连续子序列 (DP)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:5615 解决:2668 题目描述:     给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, N ...

  4. 九度OJ 1011 最长子串

    #include <iostream> #include <string> #include <sstream> #include <math.h> u ...

  5. 九度oj 1528 最长回文子串

    原题链接:http://ac.jobdu.com/problem.php?pid=1528 小白书上的做法,不过这个还要简单些... #include<algorithm> #includ ...

  6. 九度OJ 1451 不容易系列之一 -- 动态规划

    题目地址:http://ac.jobdu.com/problem.php?pid=1451 题目描述: 大家常常感慨,要做好一件事情真的不容易,确实,失败比成功容易多了! 做好“一件”事情尚且不易,若 ...

  7. 九度OJ 1500 出操队形 -- 动态规划(最长上升子序列)

    题目地址:http://ac.jobdu.com/problem.php?pid=1500 题目描述: 在读高中的时候,每天早上学校都要组织全校的师生进行跑步来锻炼身体,每当出操令吹响时,大家就开始往 ...

  8. 【九度OJ】题目1195:最长&最短文本 解题报告

    [九度OJ]题目1195:最长&最短文本 解题报告 标签(空格分隔): 九度OJ http://ac.jobdu.com/problem.php?pid=1195 题目描述: 输入多行字符串, ...

  9. 【九度OJ】题目1069:查找学生信息 解题报告

    [九度OJ]题目1069:查找学生信息 解题报告 标签(空格分隔): 九度OJ [LeetCode] http://ac.jobdu.com/problem.php?pid=1069 题目描述: 输入 ...

随机推荐

  1. ECSHOP在线手册布局参考图--商品分类页 category.dwt

        A.购物车 1,设置方法 程序自动读取购物车的商品数量 2,代码相关 cart.lbi 中 {insert_scripts files='transport.js'} <div clas ...

  2. jsp应用bootstrap表格应用实例

    一.初始化表格 <div style="margin-top: 80px;margin-left:45px;margin-right:30px;overflow-x: scroll&q ...

  3. sqlninja 说明 (转)

    首先来介绍一下sqlninja的优点. 一个专门针对Microsoft SQL Server的sql注入工具 可找到远程SQL服务器的标志和特征(版本.用户执行的查询.用户特权.xp_cmdshell ...

  4. 找回丢失的SQL Server性能计数器

    There was one time when I was delivering a Service using a tool that gathers performance data throug ...

  5. CSDN上下载的一些关于Android程序调用Webservice执行不成功的问题

    今天从书上和CSDN上找了几个关于android调用webservice的样例,这些样例从代码来看.没不论什么错误,可是就是执行不成功.分析了android调用web接口的写法,发现这些样例在调用的时 ...

  6. Lazy Load 图片延迟加载(转)

    jQuery Lazy Load 图片延迟加载来源 基于 jQuery 的图片延迟加载插件,在用户滚动页面到图片之后才进行加载. 对于有较多的图片的网页,使用图片延迟加载,能有效的提高页面加载速度. ...

  7. JAVA获取CLASSPATH路径--转

    ClassLoader提供了两个方法用于从装载的类路径中取得资源: public URL getResource(String name);         public InputStream ge ...

  8. Web页面向后台提交数据的方式和选择

    1.通过表单提交 这是HTML支持最传统的提交方法,需要创建表单,然后表单包含各种类型的表单元素,还要有一个提交按钮,通过提交按钮来提交到后台,这种方式提交后页面会刷新. 2.通过网页链接提交 可以在 ...

  9. Android之UI--重绘EditText以及实现Button的渐变色

    在本文中实现的是比较普遍的一个对EditText的重绘以及对于按钮或窗口添加渐变色. 因为EditText是继承于TextView的,所以可以实现对EditText的重绘,在重绘的时候只需要继承Edi ...

  10. ios通知-kvo

    // KVC: Key Value Coding, 常见作用:给模型属性赋值    // KVO: Key Value Observing, 常用作用:监听模型属性值的改变 // // ViewCon ...