最长上升子序列
来源:互联网 发布:网络舆论引导员工资单 编辑:程序博客网 时间:2024/06/10 19:25
刚刚开始学习动态规划,就从最长上升子序列(Longest Increasing Subsequence)开始吧。最长上升子序列是非常经典的动态规划的题目,也是很基础的题目。对于这题的有两种算法,时间复杂度分别为O(n*logn)和O(n^2) 。
动态规划求解思路分析:(O(n^2))
经典的O(n^2)的动态规划算法,设A[i]表示序列中的第i个数,F[i]表示从1到i这一段中以i结尾的最长上升子序列的长度,初始时设F[i] = 0(i = 1, 2, ..., len(A))。则有动态规划方程:F[i] = max{1, F[j] + 1} (j = 1, 2, ..., i - 1, 且A[j] < A[i])。
#include <iostream>#include <cstdio>#include <cstring>using namespace std;#define N 10005int main(){ int n, b[N], len, max; char str[N]; scanf("%d", &n); while (n--) { scanf("%s", str); len = strlen(str); b[0] = max = 1; for (int i=1; i<len; i++) { int temp = 0; for (int j=0; j<i; j++) if (str[i]>str[j] && b[j]>=temp) temp = b[j]; b[i] = temp+1; if (b[i]>max) max = b[i]; } printf("%d\n", max); } return 0;}
贪心+二分查找:(O(nlogn))
开辟一个栈,每次取栈顶元素s和读到的元素a做比较,如果a>s, 则加入栈;如果a<s,则二分查找栈中的比a大的第1个数,并替换。 最后序列长度为栈的长度。
这也是很好理解的,对x和y,如果x<y且E[y]<E[x],用E[x]替换 E[y],此时的最长序列长度没有改变但序列Q的''潜力''增大。
举例:原序列为1,5,8,3,6,7
栈为1,5,8,此时读到3,则用3替换5,得到栈中元素为1,3,8, 再读6,用6替换8,得到1,3,6,再读7,得到最终栈为1,3,6,7 ,最长递增子序列为长度4。
这里没有开辟栈,而是开了数组b[],全部赋为最大值。
#include <iostream>#include <cstdio>#include <cstring>using namespace std;#define N 10005int binary(int a[], int len, int ch)//返回x,a[x]>=ch>a[x-1]{ int left = 1, right = len; int mid = (left+right)>>1; while (left<=right) { if (a[mid]>ch) right = mid-1; else if (a[mid]<ch) left = mid+1; else return mid; mid = (left+right)>>1; } return left;}int main(){ int n, b[N], len, max; char str[N]; scanf("%d", &n); while (n--) { scanf("%s", str); len = strlen(str); for (int i=0; i<N; i++) b[i] = N; b[0] = -1, b[1] = str[0]; max = 1; for (int i=1; i<len; i++) { int t = binary(b, N, str[i]); b[t] = str[i]; if (t>max) max = t; } printf("%d\n", max); } return 0;}
对于如果要输出一个最长上升子序列的话,就要用到时间复杂度为O(n^2)的算法,就要多开辟一个数组pre[],用来存在每一个元素的前驱元素的数组下标。
核心代码如下:
for (int i=1; i<len; i++){ int temp = 0; for (int j=0; j<i; j++) if (str[i]>str[j] && b[j]>temp) { temp = b[j]; pre[i] = j;//存放前驱元素所在下标 } b[i] = temp+1;}
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- JILK - (6) - 32-Bit and 16-Bit Address and Operand Sizes
- 数据库存储索引
- 怎么使用JavaBean组件
- 树形查询中where的作用
- Ural 1141. RSA Attack 扩展欧几里得算法
- 最长上升子序列
- 实模式和保护模式
- UVA 1339
- Ministry
- Android组件的使用:Menu
- POJ-3498-March of the Penguins
- iOS简单加载一个网页
- 网站是否需要经常更新要看具体情况而定
- iOS 消息推送通知