最长单调递增子序列

解题思想:动态规划

1.解法1(n2)

 状态:d[i] = 长度为i+1的递增子序列的长度

 状态转移方程:dp[i] = max(dp[j]+1, dp[i]);

分析:最开始把dp数组初始化为1,然后从前往后考虑数列的元素,对于每个aj,如果a[i] > a[j],就用dp[i] = max(dp[i], dp[j] + 1)进行更新,再从dp数组中找出最大值即为结果

举例:abklmncdefg

      dp[0] = 1; dp[1] = 2; dp[2] = 3; dp[3] = 4; dp[4] = 5; dp[5] = 6; dp[7] = 3; dp[8] = 4; dp[9] = 5; dp[10] = 6; dp[11] = 7;  最大值为7

 代码:

 #include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAX_N = ;
int n;
char a[MAX_N];
int dp[MAX_N];
int main() {
int n;
cin >> n;
while(n--) {
int ans = ;
fill(dp, dp+MAX_N, );
cin >> a;
int len = strlen(a);
for(int i = ; i < len; i++) {
for(int j = ; j < i; j++) {
if(a[j] < a[i]) dp[i] = max(dp[i], dp[j] + );
}
ans = max(ans, dp[i]);
}
cout << ans << endl;
}
return ;
}

2.解法2(n2)

 状态:d[i] = 长度为i+1的递增子序列中末尾的最小值(不存在就是INF)

 分析:最开始用INF初始化dp数组的值,然后从前往后考虑数列的元素,对于每个aj,如果i = 0或者a[j]  >= a[i],使得a[j] = a[i]并且break出来,最后第一个dp数组中值为INF的下标即为结果

 举例:abklmncdefg

      a; ab; abk; abkl; abklm; abklmn; abclmn; abcdmn; abcden; abcdef; abcdefg; 第一个INF的下标为7 

 代码:

 #include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAX_N = ;
const int INF = ;
int n;
char a[MAX_N];
char dp[MAX_N];
int main() {
int n;
cin >> n;
while(n--) {
fill(dp, dp+MAX_N, INF);
cin >> a;
int len = strlen(a);
for(int i = ; i < len; i++) {
for(int j = ; j < len; j++) {
if(!i || dp[j] >= a[i]) {
dp[j] = a[i]; break;
}
}
}
int ans = ;
while(dp[ans] != INF) ans++;
cout << ans << endl;
}
return ;
}

3.解法3(nlogn)

 分析:思路与解法2一样,但是解法2可以进一步优化,在解法2中dp数组是单调递增的,每次要从头到尾找到第一个大于等于a[i]的值,这是o(n2)的,既然是顺序的可以使用二分查找进行改进,

    这样可以在o(nlogn)时间内求出结果,这里利用到了STL中的lower_bound(dp, dp + n, a[i]),找出dp数组中大于等于a[i]的最小的指针,upper_boundlower_bound(dp, dp + n, a[i]),找出dp数组中大于a[i]的最大的指针

代码:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX_N = ;
const int INF = ;
int n;
char a[MAX_N];
char dp[MAX_N];
int main() {
int n;
cin >> n;
while(n--) {
fill(dp, dp+MAX_N, INF);
cin >> a;
int len = strlen(a);
for(int i = ; i < len; i++) {
*lower_bound(dp, dp+len, a[i]) = a[i];
}
cout << lower_bound(dp, dp+len, INF) - dp << endl;
}
return ;
}

动态规划-最长单调递增子序列(dp)的更多相关文章

  1. [C++] 动态规划之矩阵连乘、最长公共子序列、最大子段和、最长单调递增子序列、0-1背包

    一.动态规划的基本思想 动态规划算法通常用于求解具有某种最优性质的问题.在这类问题中,可能会有许多可行解.每一个解都对应于一个值,我们希望找到具有最优值的解. 将待求解问题分解成若干个子问题,先求解子 ...

  2. HD1160FatMouse's Speed(最长单调递增子序列)

    FatMouse's Speed Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  3. 题目:[NOIP1999]拦截导弹(最长非递增子序列DP) O(n^2)和O(n*log(n))的两种做法

    题目:[NOIP1999]拦截导弹 问题编号:217 题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发 ...

  4. [dp]最长单调递增子序列LIS

    https://www.51nod.com/tutorial/course.html#!courseId=12 解题关键: 如果将子序列按照长度由短到长排列,将他们的最大元素放在一起,形成新序列$B\ ...

  5. poj1631Bridging signals(最长单调递增子序列 nlgn)

    Bridging signals Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12251   Accepted: 6687 ...

  6. NYOJ17 最长单调递增子序列 线性dp

    题目链接: http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=17 分析: i=1 dp[i]=1 i!=1 dp[i]=max(dp[j]+1) ...

  7. nyist oj 214 单调递增子序列(二) (动态规划经典)

    单调递增子序列(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描写叙述 ,a2...,an}(0<n<=100000).找出单调递增最长子序列,并求出其长度 ...

  8. ny214 单调递增子序列(二) 动态规划

    单调递增子序列(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 给定一整型数列{a1,a2...,an}(0<n<=100000),找出单调递增最长子序 ...

  9. nyoj 214——单调递增子序列(二)——————【二分搜索加dp】

    单调递增子序列(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:4   描述 给定一整型数列{a1,a2...,an}(0<n<=100000),找出单调递增最长 ...

随机推荐

  1. Hibernate的查询功能

    1.Query对象 1.使用Query对象,不需要写sql语句,但是写hql语句 (1)hql:hibernate query language,提供查询语言,这个hql语言和普通sql语句相似 (2 ...

  2. 如何用git把本地代码上传到github

    注册账户以及创建仓库 要想使用github第一步当然是注册github账号了.之后就可以创建仓库了(免费用户只能建公共仓库),Create a New Repository,填好名称后Create,之 ...

  3. 力扣(LeetCode)258. 各位相加

    给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数. 示例: 输入: 38 输出: 2 解释: 各位相加的过程为:3 + 8 = 11, 1 + 1 = 2. 由于 2 是一位数,所 ...

  4. vue模板编译

    Vue 的模板编译是在 $mount 的过程中进行的,在 $mount 的时候执行了 compile 方法来将 template 里的内容转换成真正的 HTML 代码. complie 最终生成 re ...

  5. 学习笔记13—python DataFrame获取行数、列数、索引及第几行第几列的值

    1. df=DataFrame([{‘A’:’11’,’B’:’12’},{‘A’:’111’,’B’:’121’},{‘A’:’1111’,’B’:’1211’}]) print df.column ...

  6. Asp.net core 学习笔记 (Excel 读写)

    EPPlus 已经支持 .net core 了 https://www.nuget.org/packages/EPPlus https://github.com/JanKallman/EPPlus 写 ...

  7. R语言函数总结(转)

    R语言特征 对大小写敏感 通常,数字,字母,. 和 _都是允许的(在一些国家还包括重音字母).不过,一个命名必须以 . 或者字母开头,并且如果以 . 开头,第二个字符不允许是数字. 基本命令要么是表达 ...

  8. 雷林鹏分享:C# 判断

    C# 判断 判断结构要求程序员指定一个或多个要评估或测试的条件,以及条件为真时要执行的语句(必需的)和条件为假时要执行的语句(可选的). 下面是大多数编程语言中典型的判断结构的一般形式: 判断语句 C ...

  9. Es6构造函数的变身,通常我们称为类

    以前我们使用ES5标准定义一个构造函数的过程如下: function Person(name,age){ this.name = name; this.age = age; //私有变量 var el ...

  10. hdu-2089 不要62 基础DP 模板

    http://acm.hdu.edu.cn/showproblem.php?pid=2089 数位DP的思想时预处理以x开头长度为len的数(例如 x000~x999)的所有情况.给出一个数,可以在l ...