动态规划-最长单调递增子序列(dp)
解题思想:动态规划
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)的更多相关文章
- [C++] 动态规划之矩阵连乘、最长公共子序列、最大子段和、最长单调递增子序列、0-1背包
一.动态规划的基本思想 动态规划算法通常用于求解具有某种最优性质的问题.在这类问题中,可能会有许多可行解.每一个解都对应于一个值,我们希望找到具有最优值的解. 将待求解问题分解成若干个子问题,先求解子 ...
- HD1160FatMouse's Speed(最长单调递增子序列)
FatMouse's Speed Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- 题目:[NOIP1999]拦截导弹(最长非递增子序列DP) O(n^2)和O(n*log(n))的两种做法
题目:[NOIP1999]拦截导弹 问题编号:217 题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发 ...
- [dp]最长单调递增子序列LIS
https://www.51nod.com/tutorial/course.html#!courseId=12 解题关键: 如果将子序列按照长度由短到长排列,将他们的最大元素放在一起,形成新序列$B\ ...
- poj1631Bridging signals(最长单调递增子序列 nlgn)
Bridging signals Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 12251 Accepted: 6687 ...
- 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) ...
- nyist oj 214 单调递增子序列(二) (动态规划经典)
单调递增子序列(二) 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描写叙述 ,a2...,an}(0<n<=100000).找出单调递增最长子序列,并求出其长度 ...
- ny214 单调递增子序列(二) 动态规划
单调递增子序列(二) 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 给定一整型数列{a1,a2...,an}(0<n<=100000),找出单调递增最长子序 ...
- nyoj 214——单调递增子序列(二)——————【二分搜索加dp】
单调递增子序列(二) 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 给定一整型数列{a1,a2...,an}(0<n<=100000),找出单调递增最长 ...
随机推荐
- openmodelica警告及错误
Warning: The initial conditions are not fully specified. simulate(TCS.TCS,startTime=0,stopTime=200.0 ...
- 力扣(LeetCode) 961. 重复 N 次的元素
在大小为 2N 的数组 A 中有 N+1 个不同的元素,其中有一个元素重复了 N 次. 返回重复了 N 次的那个元素. 示例 1: 输入:[1,2,3,3] 输出:3 示例 2: 输入:[2,1,2, ...
- Vue 中 export及export default的区别
相信很多人都在vue使用过export.export default.import,然而它们到底有什么区别呢? 在ES6中,export与export default均可用于导出常量.函数.文件.模块 ...
- Qt的QVariant类
QStandardItemModel类中的函数 bool setData(const QModelIndex &index, const QVariant &value, int ro ...
- feature map 大小以及反卷积的理解
(1)边长的计算公式是: output_h =(originalSize_h+padding*2-kernelSize_h)/stride +1 输入图片大小为200×200,依次经过一层卷积(ke ...
- centos如何查看linux内核,版本号
[root@localhost ~]# uname -a Linux localhost.localdomain -.el7.x86_64 # SMP Thu Nov :: UTC x86_64 x8 ...
- (转)C# System.Diagnostics.Process.Start使用
经常会遇到在Winform或是WPF中点击链接或按钮打开某个指定的网址, 或者是需要打开电脑中某个指定的硬盘分区及文件夹, 甚至是"控制面板"相关的东西, 如何做呢? 方法:使用 ...
- p1459 Sorting a Three-Valued Sequence
如果将1和3都放到正确的位置,2自然也在正确的位置.那么统计1,2,3的数量num1,num2,num3.再看前num1个数有几个(设x个)不是1,那么x个1肯定要移.设前num1个数有y个3,最后n ...
- Spring Batch 使用场景
一个标准的批处理程序通常会从数据库,文件或者队列中读取大量的数据和记录,然后对获取的数据进行处理,然后将修改后的格式写回到数据库中. 通常 Spring Batch 在离线模式下进行工作,不需要用户干 ...
- display:inline-block与float
display:inline-block 既有行级元素的特性,也有块级元素的特性,因此在同一行,能设置宽高,margin,padding inline-block和float的区别 虽然设置float ...