最大上升子序列.docVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
最大上升子序列

《最长上升子序列问题》 1.问题描述: 给定一个整数序列A1A2A3….An。求它的一个递增子序列,使子序列的元素个数尽量多。比如序列1 6 3 5 4 2 7的最长上升子序列是1347。 2.算法: 最长上升子序列问题具有最有子结构特性,基本算法是找到一个比前面某一个数较大的大数,把这个数作为可能加在原来序列后面的一个数。只有当以这个大数结尾的上升子序列的原始长度比以前面某一个被比较的数结尾的上升子序列长度打时才真正的把这个大数加在原来序列后面产生新的当前最大上升子序列。 具体算法为:arr[]保存要求的输入序列,n为数列长度,dp[i]用来存放以第i个数结尾的上升子序列长度,pre[i]表示符合要求的第i个元素的前一个元素的下标;temp用来标记符合要求的元素,便于输出。 算法复杂度为O(n2),外层循环i控制从第一个数到最后一个数的遍历,选定可能序列的最后一位数;内层循环j用来控制从第一个到i-1个元素和第i个元素比较。 dp状态转移方程: [i] = max{1, dp[j] }+1 (j = 1, 2, 3, ..., i-1 且 A[j] A[i])O(n^2),这个算法其实是DP。本来有N个数要处理是O(n),每次计算要查找N次还是O(n),一共就是O(n^2)。#includeiostream using namespace std; int dp[1000],pre[1000],temp[1000];//dp[i]用来存放从第一位数开始,以第i位数结尾的上升子序列序列长度;pre[i]表示符合要求的第i个元素的前一个元素的下标;temp用来标记符合要求的元素,便于输出。 int LIS(int arr[1000], int n) { for(int i=1; i=n;i++) { dp[i] = 0;//初始化长度为; pre[i]=-1;// temp[i]=0; } int ans,k,i,j,end=0;//ans用来暂存当前一次循环的最大长度;end存放符合要求的最大上升子序列的最后一位元素下标 dp[1] = 1;//初始化dp[1] for(i=2; i=n; i++)//外循环从第二个元素遍历到最后一个 { ans = dp[i]; for( j=1; ji; j++) //内循环从第一个元素开始比较,到第i个结束 { if(arr[i]arr[j] dp[j]=ans)//arr[i]比arr[j]大并且dp[j]大于当前的最大长度时更新ans并给pre【i】赋值,便于输出时找到arr【i】的前一个元素 { ans = dp[j]; pre[i]=j; } } dp[i] = ans+1;//加上arr【i】,所以长度加一 } ans = 0; for(i=1; i=n; i++)//找到最大长度 { if(dp[i] ans) { ans = dp[i]; end=i; } } k=end; temp[k]=1; while(k=0)//对符合要求的那一组最大上升子序列进行标记 { k=pre[k];//用于找到下一个要标记的元素下表,跳转 temp[k]=1; } cout最大上升子序列为:; for( i=1;i=n;i++)//输出标记好的元素 if(temp[i]==1) coutarr[i] ; return ans; } void main() { int i, n, arr[1000]; while(1) { cout请输入序列长度endl; cinn; cout请输入n位数字endl; for(i=1;i=n;i++) cinarr[i]; cout最大上升子序列长度为LIS(arr,n)endlendlendl; } }

文档评论(0)

jgx3536 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

版权声明书
用户编号:6111134150000003

1亿VIP精品文档

相关文档