首页 > 代码库 > 各种子序列问题
各种子序列问题
最长严格上升子序列
LIS问题,动归时间复杂度o(n2),可以用单调队列优化到o(nlogn)
http://blog.csdn.net/dangwenliang/article/details/5728363
#include<iostream>#include<cstdio>#include<algorithm>using namespace std;int n,dp[5005],orz[5005],ans = 0;int main(){ cin>>n; for(int i = 1;i <= n;i++) scanf("%d",&orz[i]); for(int i = 1;i <= n;i++){ dp[i] = 1; for(int j = 1;j < i;j++){ if(orz[i] > orz[j])dp[i] = max(dp[i],dp[j]+1); ans = max(ans,dp[i]); } } cout<<ans; return 0;}
#include <iostream>using namespace std;int find(int *a,int len,int n)//修改后的二分查找,若返回值为x,则a[x]>=n{ int left=0,right=len,mid=(left+right)/2; while(left<=right) { if(n>a[mid]) left=mid+1; else if(n<a[mid]) right=mid-1; else return mid; mid=(left+right)/2; } return left;} int main(void){ int n,a[100],c[100],i,j,len;//新开一变量len,用来储存每次循环结束后c中已经求出值的元素的最大下标 while(cin>>n) { for(i=0;i<n;i++) cin>>a[i]; b[0]=1; c[0]=-1; c[1]=a[0]; len=1;//此时只有c[1]求出来,最长递增子序列的长度为1. for(i=1;i<n;i++) { j=find(c,len,a[i]); c[j]=a[i]; if(j>len)//要更新len,另外补充一点:由二分查找可知j只可能比len大1 len=j;//更新len } cout<<len<<endl; } return 0;}
合唱队形
#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<algorithm>using namespace std;const int maxn = 200;int dp[maxn],dps[maxn],value[maxn],n;int main(){ cin>>n; for(int i =1;i <= n;i++) cin>>value[i]; dp[1] = dps[n] = 1; for(int i = 2;i <= n;i++){ for(int j = 1;j < i;j++){ if(dp[j] > dp[i] && value[i] > value[j]) dp[i] = dp[j]; } dp[i]++; } for(int i = n-1;i >= 1;i--){ for(int j = n;j > i;j--){ if(dps[j] > dps[i] && value[i] > value[j]) dps[i] = dps[j]; } dps[i]++; } int ans = 0; for(int i = 1;i <= n;i++) ans = max(ans,dp[i] + dps[i] - 1); cout<<n - ans; return 0;}
各种子序列问题
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。