ny-单调递增最长子序列
2015-06-01 18:19
267 查看
单调递增最长子序列
时间限制:3000 ms | 内存限制:65535 KB难度:4
描述求一个字符串的最长递增子序列的长度
如:dabdbf最长递增子序列就是abdf,长度为4
输入第一行一个整数0<n<20,表示有n个字符串要处理
随后的n行,每行有一个字符串,该字符串的长度不会超过10000
输出输出字符串的最长递增子序列的长度
样例输入
3 aaa ababc abklmncdefg
样例输出
1 3 7
解题思路
先解释下什么叫子序列。若a序列删去其中若干个元素后与b序列完全相同,则称b是a的子序列。
我们假定存在一个单调序列{An}(以递增序列为例),现在在其后面添加一个元素a(n+1), 有两种情况: 1.a(n+1)>a(n)。 此时,a(n+1)可以添加到An序列的尾部,形成一个新的单调序列, 并且此序列长度大于之前An的长度; 2.a(n+1)<=a(n)。此时,a(n+1)当然不可以添加到An序列的尾部。 经过分析,我们可以得出这样的结论: 一个单调序列与其后面元素的关系仅与此序列的末尾元素有关。 如此,便有了此题如下的dp解法: 建立一个一维数组dp[ ],用dp[i]保存长度为i的单调子序列的末尾元素的值, 用top保存单调子序列的最大长度。 初始top=1,dp[1]=a1; 然后,我们从前向后遍历序列An(i : 2~n)。显然,我们会遇到两种情况: 1.a[i] > dp[top]。 此时,我们把a[i]加入到长度为top的单调序列中,这时序列长度为top+1, top值也跟着更新,即dp[++top] = a[i]; 2.a[i]<=dp[top]。 此时,a[i]不能加入长度为top的单调序列,那它应该加入长度为多少的序列呢? 做法是,从前向后遍历dp[ ] (j: 1~top-1),直到满足条件 a[i] > dp[j], 此时,我们将dp[j]的值更新为a[i]。 可是,为什么要更新它呢? 因为对于相同长度的单调递增序列来说,末尾元素的值越小, 其后元素加入此序列的可能性越大,也就是说,我们这样做,是为了防止丢失最优解。
例:
s abclmndefg dp abclmn abcdmn abcden ... abcdefg
代码
#include<stdio.h> #include<string.h> char s[11000],dp[11000]; int main() { int n; int len; int i,j,k; int max; scanf("%d",&n); while(n--) { scanf("%s",s); len=strlen(s); memset(dp,0,sizeof(dp)); dp[1]=s[0]; max=1; for(i=1;i<len;i++) { if(s[i]>dp[max]) dp[++max]=s[i]; else { for(j=1;s[i]>dp[j];j++) { } dp[j]=s[i]; } } printf("%d\n",max); } return 0; }
[/code]
相关文章推荐
- IUSR和IIS_IUSRS
- 提取 Microsoft.ReportViewer等dll
- iOS中Objective-C与JavaScript之间相互调用的实现(实现了与Android相同的机制)
- HDU 2896 病毒侵袭(AC自动机)
- AsyncTask实现ListView中异步加载网络图片
- Spring学习笔记——关于Spring注解扫描不能注入new对象问题
- Java for LeetCode 131 Palindrome Partitioning
- 把多個文件壓縮成zip文件然後實現下載
- 如何显示html代码到新窗口界面中
- 本人的博客迁移到多个平台,小伙伴们多多支持……
- 第十一周 项目四 类族的设计】
- 如何解决XML文件中的警告提示“No grammar constraints (DTD or XML Schema) referenced in the document.”
- ubuntu中安装Docker
- PHP获取POST数据的三种方法
- CSS: Float a div on another div, Ex: Text caption on picture
- 解決google在scroll裡左右拖動的問題
- C++网络编程概述(精)
- 验证码(随机数字+字符,数字加减)
- 给Repeater控件里添加序号的5种方法
- 读取自定义模型文件,绘制模型