LIS LCS 最长上升子序列 最长公共子序列 ...
最长上升子序列,问题定义:http://blog.csdn.net/chenwenshi/article/details/6027086
代码:
public static void getData( char[] L )
{
int len = L.length;
int[] f = new int[len];
String[] res = new String[len];
for( int i = ; i < len; i++ )
{
f[i] = ;
res[i] = "" + L[i];
for( int j = ; j < i; j++ )
{
if( (L[j] - '') < (L[i]-'') && f[j] + > f[i] )
{
f[i] = f[j] + ;
res[i] = res[j] + " " + L[i];
}
}
/* 下标连续递增子序列
if( (L[i-1] - '0') == (L[i]-'0') - 1 )
{
f[i] = f[i-1] + 1;
res[i] = res[i-1] + " " + L[i];
}
/**/
}
// System.out.println( f[ len - 1 ]);
int max = f[];
int maxK = ;
for( int k = ; k < len; k++ )
{
if( f[k] > max )
{
max = f[k];
maxK = k;
}
}
System.out.println( f[ maxK ]);
for( int k = ; k < len; k++ )
{
if( f[k] == max )
{
System.out.println( res[k] );
}
}
}
最大和子序列(最大和连续子序列)。MaxSum[i] 表示以i结尾的有最大和的连续子序列之和。MaxSum[i] = Max{ MaxSum[i-1] + A[i], A[i]}; 以下代码没有设置数组MaxSum[]。
题目描述:http://blog.csdn.net/hs794502825/article/details/7956730
public static void getMax( String[] L )
{
int thisSum = 0, maxSum = 0;
int begin=0,end = 0;
int max = 0; //String[] res = new String[L.length];
//res[0] = "" + L[0];
for( int j = 1; j < L.length; j++ )
{
thisSum += Integer.parseInt( L[j] );
if( thisSum > maxSum )
{
maxSum = thisSum;
//max = j;
end = j;
}
if( thisSum < 0 )
{
thisSum = 0;
begin = j+1;
}
//res[j] = res[j-1] + " " + L[j];
//end = j;
} System.out.println( maxSum ); for( int k = begin; k <= end; k++ )
{
System.out.print( L[k] + " " );
} }
L1与L2的最长公共子序列:
public static void getLCS( char[] x, char[] y )
{
int m = x.length;
int n = y.length;
int[][] c = new int[m+1][n+1];
int[][] b = new int[m+1][n+1];
for( int row = 0; row < m; row ++ )
{
int i = row + 1;
for( int col = 0; col < n; col ++ )
{
int j = col + 1;
if( x[row] == y[col] )
{
c[i][j] = c[i-1][j-1] + 1;
b[i][j] = 0;
}
else if( c[i-1][j] > c[i][j-1] )
{
c[i][j] = c[i-1][j];
b[i][j] = 1;
}
else if( c[i-1][j] < c[i][j-1] )
{
c[i][j] = c[i][j-1];
b[i][j] = 2;
}
else
{
c[i][j] = c[i][j-1];
b[i][j] = 3;
}
}
} int i = m;
int j = n;
Stack< Character > stack = new Stack< Character >();
while( (i != 0) && ( j != 0) )
{
if( b[i][j] == 0 )
{
//System.out.println( x[m] );
stack.push(x[i-1]);
i -= 1;
j -= 1;
}
else if( b[i][j] == 1 )
{
i -= 1;
}
else
{
j -= 1;
}
}
while( !stack.isEmpty() )
{
System.out.print( stack.pop() );
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
String a = "abcdeabcdefg";
String b = "acdeafdc";
getLCS( a.toCharArray(), b.toCharArray() );
}
装信封问题:
N个信封,给出宽、高。小信封装在大信封里,求这些信封最多能嵌套的层数。
第一行为N,接下来N行每行两个整数,分别表示宽与高。
4
5 4
6 4
6 7
2 3
这个问题可以转化为最长递增子序列问题。首先按照宽度将N个信封由小到大排序,当宽度相同时,按高度从大到小排序:2 3, 5 4, 6 7, 6 4。防止了当宽度相同时,高度小的嵌套进高度大的信封。代码如下:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std; bool cmp( const pair<int,int>& x, const pair<int,int>& y )
{
return x.first != y.first ? x.first < y.first : x.second > y.second;
}
int findMax( vector< pair< int, int > > e )
{
int n = e.size();
if( n == )
{
return ;
} sort( e.begin(), e.end(), cmp ); vector<int> dp(n,);
for( int i = ; i < n; i++ )
{
//dp[i] = 1;
for( int j = ; j < i; j++ )
{
if( ( dp[i] < dp[j]+ ) && ( e[i].second > e[j].second ) && ( e[i].first > e[j].first ) )
{
dp[i] = dp[j]+;
}
}
}
int maxv = ;
for( int i = ; i < n; i++ )
{
if( dp[i] > maxv )
{
maxv = dp[i];
}
} // O(nlogn):
// http://blog.csdn.net/shuangde800/article/details/7474903
// http://www.jiuzhang.com/solutions/russian-doll-envelopes/
// 当有多个子序列s1,s2,,,内元素数为均为k个时,选择si,si的第k个元素比其他s1,s2...的第k个元素都小
// 数组d[k]即表示,当上升子序列元素个数为k时,si中第k个元素的值
vector< int > d( n+, );
int len = ;
for( int k = ; k < n; k++ )
{
if( d[len] < e[k].second )
{
d[++len] = e[k].second;
}
else
{
//需要找到比d[mid]大的第一个位置,即插入数据的位置 //d数组中的元素不会重复,用二分插入排序查找插入位置就可以
//index: 1 2 3 4 5
//value: a a a a b
//区别:
//查找下界的二分查找,查找a时返回第一个a的位置1
//二分插入排序查找插入位置,插入a时,返回最后一个a的下一个位置6 //stl中binary_search函数功能是查看某一值在一个已经排好序的序列中是否存在,
//当存在时返回true,否则返回false //如果所要查找的元素只有一个,那么lower_bound()返回了这个元素的地址,不是下标
//如果相同元素出现了多次,那么lower_bound()找到了第一个所找元素的地址
//即:返回第一个大于或等于val的元素的地址
//upper_bound返回第一个大于val元素的地址
//算法竞赛入门 p.125 int left=, right=len, mid, j = -;
while( left <= right )
{
mid = ( left + right )/;
//当 d[mid] 与 e[k].second(待插入数值)相等时,left也要置为mid+1,
//这也保证也二分插入排序是稳定的
if( d[mid] > e[k].second )
{
right = mid - ;
}
else
{
left = mid + ;
}
} // left; 待插入数据位置,第一个待插入数字大的位置
d[ left ] = e[k].second;
}
}
cout << len << "+++++++" << endl; return maxv;
} int main()
{
vector< pair< int, int > > e;
int n;
cin >> n;
int a, b;
for( int i = ; i < n; i++ )
{
cin >> a >> b;
e.push_back( make_pair<int,int>( a, b ) );
} cout << findMax( e );
return ;
}
在O(nlogn)的实现中,还引申出了二分查找的上下界问题。
另外,当要求最长不下降子序列时,这篇文章给出了很好的分析:http://www.cnblogs.com/itlqs/p/5743114.html
LIS LCS 最长上升子序列 最长公共子序列 ...的更多相关文章
- DP_最长公共子序列/动规入门
学自:https://open.163.com/movie/2010/12/L/4/M6UTT5U0I_M6V2U1HL4.html 最长公共子序列:(本文先谈如何求出最长公共子序列的长度,求出最长公 ...
- 最长公共子序列(LCS)和最长递增子序列(LIS)的求解
一.最长公共子序列 经典的动态规划问题,大概的陈述如下: 给定两个序列a1,a2,a3,a4,a5,a6......和b1,b2,b3,b4,b5,b6.......,要求这样的序列使得c同时是这两个 ...
- 算法设计 - LCS 最长公共子序列&&最长公共子串 &&LIS 最长递增子序列
出处 http://segmentfault.com/blog/exploring/ 本章讲解:1. LCS(最长公共子序列)O(n^2)的时间复杂度,O(n^2)的空间复杂度:2. 与之类似但不同的 ...
- 最长递增子序列(lis)最长公共子序列(lcs) 最长公共上升子序列(lics)
lis: 复杂度nlgn #include<iostream> #include<cstdio> using namespace std; ],lis[],res=; int ...
- 最长公共子序列-LCS问题 (LCS与LIS在特殊条件下的转换) [洛谷1439]
题目描述 给出1-n的两个排列P1和P2,求它们的最长公共子序列. 输入 第一行是一个数n, 接下来两行,每行为n个数,为自然数1-n的一个排列. 输出 一个数,即最长公共子序列的长度 输入样例 5 ...
- 最长上升子序列(LIS)与最长公共子序列(LCS)
1.LIS : 给定一个序列,求它的最长上升子序列(n<=2000) 第一种 O(n^2): dp[i] 为以i为开头的最长上升子序列长度 code1: #include<cstdio&g ...
- 最长连续公共子序列(LCS)与最长递增公共子序列(LIS)
最长公共子序列(不连续) 实际问题中也有比较多的应用,比如,论文查重这种,就是很实际的一个使用方面. 这个应该是最常见的一种了,不再赘述,直接按照转移方程来进行: 按最普通的方式就是,直接构造二维矩阵 ...
- 最长公共子序列(LCS)、最长递增子序列(LIS)、最长递增公共子序列(LICS)
最长公共子序列(LCS) [问题] 求两字符序列的最长公共字符子序列 问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字 ...
- 【线型DP模板】最上上升子序列(LIS),最长公共子序列(LCS),最长公共上升子序列(LCIS)
BEGIN LIS: 一个数的序列bi,当b1 < b2 < … < bS的时候,我们称这个序列是上升的.对于给定的一个序列(a1, a2, …, aN),我们可以得到一些上升的子序 ...
- 【LCS,LIS】最长公共子序列、单调递增最长子序列
单调递增最长子序列 时间限制:3000 ms | 内存限制:65535 KB 难度:4 描述 求一个字符串的最长递增子序列的长度如:dabdbf最长递增子序列就是abdf,长度为4 输入 ...
随机推荐
- How to Pronounce Word vs. World
How to Pronounce Word vs. World Share Tweet Share Tagged With: Comparison, Dark L What is the differ ...
- ReactiveX 学习笔记(19)使用 RxSwift + RxCocoa 进行 GUI 编程
课题 程序界面由3个文本编辑框和1个文本标签组成. 要求文本标签实时显示3个文本编辑框所输入的数字之和. 文本编辑框输入的不是合法数字时,将其值视为0. 3个文本编辑框的初值分别为1,2,3. 创建工 ...
- Extjs实现Grid表格显示【一】
Ext.onReady(function(){ // Ext.Msg.alert("提示","hello world!! "); var stu =new Ex ...
- 如何在Windows下安装MYSQL,并截图说明
说明 : window 下安装 mysql 虽然简单,但是细节不注意就会安装失败,特别是配置服务器时,Current Root Password:为空:如果输入密码了在后面安装会报错.(不知道设置这个 ...
- tf.pad(one_hot_encoding, [[0, 0], [1, 0]], mode='CONSTANT')
tf.pad(one_hot_encoding, [[0, 0], [1, 0]], mode='CONSTANT') tf.pad 是扩展的意思,其中[0, 0], [1, 0] 分别代表的是[上, ...
- linux下面设置密码失效参考
chage -E 2005-12-31 user1 设置用户口令的失效期限
- SIGTERM、SIGKILL、SIGINT和SIGQUIT的区别
转自:http://blog.csdn.net/dai_xiangjun/article/details/41871647 SIGQUIT 在POSIX兼容的平台,SIGQUIT是其控制终端发送到进程 ...
- NDK环境搭建方法2
1.新建项目NDKDemo3 2.新建com.example.shixm.ndkdemo3.MyNdk.java 3.右键main文件夹,New->Folder->JNI Folder 4 ...
- pta l2-14(列车调度)
题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805063166312448 题意:给定n个数的重排列,求至少需 ...
- Ant 初级入门
一.Ant简介 Ant是一个Apache基金会下的跨平台的构件工具. 由于Ant是基于Java的,所以需要Java环境的支持,也就是配置好 JAVA_HOME 和 ANT_HOME 环境变量分别指向J ...