最长单调递增子序列

本文介绍了解决最长上升子序列问题的两种方法:一种是通过覆盖法实现,利用循环比较并更新最优解;另一种方法则是使用新数组记录每个元素对应的最长上升子序列长度,并通过递推的方式找出最终的最大值。此外,还提到了对于覆盖法中查找过程的一种优化手段——二分查找。

方法1:覆盖法

#include<iostream> #include<string.h> using namespace std; char a[10001]; char b[10001]; int main() { int n; cin>>n; while(n--) { int len, sum = 1, i, j; //sum是最优解的个数 cin>>a; len = strlen(a); b[0] = a[0]; //循环需要比较,则先赋值 for(i = 0; i < len; ++i) //对第i个元素操作 { for(j = sum -1; j >= 0; --j) //从后先前,查找要覆盖的元素的下标 { if(a[i] > b[j]) //满足条件则续尾,不满足条件覆盖 break; } b[j + 1] = a[i]; if(j == sum -1) sum++; //续尾后最大长度+1 } cout<<sum<<endl; } return 0; }

方法2:新数组记录字串长度

#include<iostream> #include<string> #include<algorithm> using namespace std; int main() { int m; cin>>m; while(m--) { int a[10010], i; string str; cin>>str; for(i = 0; i != str.size(); i++) { a[i] = 1; for(int j = 0; j < i; j++) { if((str[j] < str[i]) && (a[i] < a[j] + 1)) //a[i]<a[j]+1:求得第i个元素前最长公共子序列长度的限制条件 a[i] = a[j] + 1; //递推 } } cout<<*max_element(a, a + i)<<endl; } return 0; }

优化方法:

在查找要覆盖的元素j的下标时,使用二分查找即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值