longestIncreasingSequence最长上升子序列问题
package dp; /**
* 最长上升子序列问题
*/
public class LongestIncreasingSubsequence
{
/**
* 原始dp
* @param arr
* @return
*/
public static int maxLength(int[] arr)
{
int[] len = new int[arr.length] ; //以i为结尾的最长上升子序列
int[] mark = new int[arr.length] ;//标记以i为结尾的最长上升子序列的上一个节点所在的上上子序列位置
len[0] = 1 ;
mark[0] = -1 ; int maxPos = 0 ;
for(int i=1 ; i<len.length ; i++)
{
len[i] = 1 ;
mark[i] = -1 ;
for(int j=i-1 ; j>=0 ; j--)
{
if(arr[j] < arr[i] && (len[j]+1) > len[i])
{
len[i] = len[j]+1 ;
mark[i] = j ;
} }
if(len[maxPos] < len[i])
maxPos = i ;
} int maxP = maxPos ;
while (maxP != -1)
{
System.out.println(arr[maxP]);
maxP = mark[maxP] ;
}
return len[maxPos] ;
} /**
* 使用二分加速的dp
* @param arr
* @return
*/
public static int maxLength2(int[] arr)
{
int[] len = new int[arr.length] ; //以i为结尾的最长上升子序列
int[] mark = new int[arr.length] ;//标记以i为结尾的最长上升子序列的上一个节点所在的上上子序列位置
int[] m = new int[arr.length+1] ;//标记长度为x的子序列的最小值在arr中的位置 int mLength = 1 ;
len[0] = 1 ;
mark[0] = -1 ;
m[1] = 0 ; int maxPos = 0 ;
for(int i=1 ; i<len.length ; i++)
{
len[i] = 1 ;
mark[i] = -1 ; int pos = binarySearch(arr , m , mLength , arr[i]) ; if(pos != -1)
{
len[i] = len[pos]+1 ;
mark[i] = pos ;
} if(mLength < len[i])
{
m[len[i]] = i ;
mLength++ ;
}
else if(arr[m[len[i]]] > arr[i])
{
m[len[i]] = i ;
} if(len[maxPos] < len[i])
maxPos = i ;
} int maxP = maxPos ;
while (maxP != -1)
{
System.out.println(arr[maxP]);
maxP = mark[maxP] ;
}
return len[maxPos] ;
} /**
* 寻找arr中比k小的最大数
* @param n 表示m的长度
* @param m 表示标记长度为x的子序列的最小值的位置的数组
* @return 该元素在arr中的位置(为标记函数而服务的)
*/
private static int binarySearch(int[] arr , int[] m , int n , int k) {
int lo = 1;
int hi = n; while ((hi-lo) > 1)
{
int mid = lo + (hi-lo)/2 ; if(arr[m[mid]] < k)
lo = mid ;
else
hi = mid ;
} if(arr[m[hi]] < k)
return m[hi] ;
else if(arr[m[lo]] < k)
return m[lo] ;
else
return -1 ;
} public static void main(String[] args) {
int[] arr = new int[]{
// 1,4,8,3,4,5
// 3,5,1,7,5,9,3,5
1, 7, 3, 5, 9, 4, 1
} ; System.out.println(maxLength2(arr));
}
}
//http://blog.csdn.net/code_pang/article/details/8757380
//http://blog.csdn.net/chenwenshi/article/details/6027086
longestIncreasingSequence最长上升子序列问题的更多相关文章
- 用python实现最长公共子序列算法(找到所有最长公共子串)
软件安全的一个小实验,正好复习一下LCS的写法. 实现LCS的算法和算法导论上的方式基本一致,都是先建好两个表,一个存储在(i,j)处当前最长公共子序列长度,另一个存储在(i,j)处的回溯方向. 相对 ...
- 动态规划之最长公共子序列(LCS)
转自:http://segmentfault.com/blog/exploring/ LCS 问题描述 定义: 一个数列 S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 ...
- [Data Structure] LCSs——最长公共子序列和最长公共子串
1. 什么是 LCSs? 什么是 LCSs? 好多博友看到这几个字母可能比较困惑,因为这是我自己对两个常见问题的统称,它们分别为最长公共子序列问题(Longest-Common-Subsequence ...
- 动态规划求最长公共子序列(Longest Common Subsequence, LCS)
1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...
- LintCode 77: 最长公共子序列
public class Solution { /** * @param A, B: Two string. * @return: the length of the longest common s ...
- 最长下降子序列O(n^2)及O(n*log(n))解法
求最长下降子序列和LIS基本思路是完全一样的,都是很经典的DP题目. 问题大都类似于 有一个序列 a1,a2,a3...ak..an,求其最长下降子序列(或者求其最长不下降子序列)的长度. 以最长下降 ...
- 删除部分字符使其变成回文串问题——最长公共子序列(LCS)问题
先要搞明白:最长公共子串和最长公共子序列的区别. 最长公共子串(Longest Common Substirng):连续 最长公共子序列(Longest Common Subsequence,L ...
- [BZOJ3173][Tjoi2013]最长上升子序列
[BZOJ3173][Tjoi2013]最长上升子序列 试题描述 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字,我们都想知道此时最长上 ...
- 3173: [Tjoi2013]最长上升子序列
原题:http://www.lydsy.com/JudgeOnline/problem.php?id=3173 题解:促使我写这题的动力是,为什么百度遍地是Treap,黑人问号??? 这题可以用线段树 ...
随机推荐
- 【CCF】地铁修建 改编Dijkstra
[题意] 给定有n个点,m条边的无向图,没有平行边和自环,求从1到n的路径中,最长段的最小值(最短路不再是路径和,而是所有段中的最大值) [AC] #include<iostream> # ...
- 反射+注解:excel2module
package test.excelTest; import java.io.File; import java.io.FileInputStream; import java.lang.reflec ...
- 反汇编角度->C++ const
#include<iostream> #include<stdlib.h> using namespace std; const int &add( const int ...
- Redis监控工具—Redis-stat、RedisLive
Redis监控工具—Redis-stat.RedisLive https://blog.csdn.net/u010022051/article/details/51104681
- Codeforces 551E GukiZ and GukiZiana(分块思想)
题目链接 GukiZ and GukiZiana 题目大意:一个数列,支持两个操作.一种是对区间$[l, r]$中的数全部加上$k$,另一种是查询数列中值为$x$的下标的最大值减最小值. $n < ...
- sudo apt-get upgrade 不成功遇到问题
一. sudo apt-get update 和 sudo apt-get upgrade 出错:(Ubuntu更新过程被中断后的问题) Ubuntu的更新过程是先下载完源里的文件就开始执行升级,如果 ...
- DNS重绑定DNS Rebinding攻击
DNS重绑定DNS Rebinding攻击 在网页浏览过程中,用户在地址栏中输入包含域名的网址.浏览器通过DNS服务器将域名解析为IP地址,然后向对应的IP地址请求资源,最后展现给用户.而对于域名所有 ...
- Android图片加载神器之Fresco,基于各种使用场景的讲解
Fresco是Facebook开源Android平台上一个强大的图片加载库,也是迄今为止Android平台上最强大的图片加载库. 优点:相对于其他开源的第三方图片加载库,Fresco拥有更好的内存管理 ...
- TCP通过滑动窗口和拥塞窗口实现限流,能抵御ddos攻击吗
tcp可以通过滑动窗口和拥塞算法实现流量控制,限制上行和下行的流量,但是却不能抵御ddos攻击. 限流只是限制访问流量的大小,是无法区分正常流量和异常攻击流量的. 限流可以控制本软件或者应用的流量大小 ...
- Apache和IIS共享80端口的四个设置方法
方法一:IIS5,多IP下共存,IIS为192.168.0.1,apache为192.168.0.2c:\Inetpub\Adminscriptscscript adsutil.vbs set w3s ...