最长不下降子序列
题目:
设有由n(1≤n≤200))个不相同的整数组成的数列,记为:b(1)、b(2)、……、b(n)b(1)、b(2)、……、b(n)若存在i1<i2<i3<…<ie 且有b(i1)<=b(i2)<=…<=b(ie)则称为长度为e的不下降序列。程序要求,当原数列出之后,求出最长的不下降序列。
例如13,7,9,16,38,24,37,18,44,19,21,22,63,15
。例中13,16,18,19,21,22,63
就是一个长度为7的不下降序列,同时也有7 ,9,16,18,19,21,22,63
组成的长度为8的不下降序列。
输入
第一行为n,第二行为用空格隔开的n个整数。
输出
第一行为输出最大个数max(形式见样例);
第二行为max个整数形成的不下降序列,答案可能不唯一,输出一种就可以了。
1.
#include<iostream> #include<cstdio> using namespace std; int n,a[1001],f[1001],p[1001]; void dfs(int i) { if(p[i]>0) dfs(p[i]); cout<<a[i]<<" "; } int main() { int n,ans; cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; } f[1]=1; p[1]=0; for(int i=2;i<=n;i++) { f[i]=0; for(int j=1;j<i;j++) { if(a[j]<=a[i]&&f[i]<f[j]) { f[i]=f[j]; p[i]=j; } } f[i]++; } ans=f[1]; int k=1; for(int i=2;i<=n;i++) { if(f[i]>ans) { k=i; ans=f[i]; } } cout<<"max="<<ans<<endl; dfs(k); return 0; }
2.优化
#include<iostream> #include<cstdio> using namespace std; int n,a[1001],f[1001]; int cnt; void dfs(int i) { if(f[i]>0) dfs(f[i]); cout<<a[i]<<" "; } int main() {//hello hello~ int n,k; cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; } f[1]=a[1]; int ans=f[1]; cnt=1; for(int i=2;i<=n;i++) { int l=1,r=cnt+1; f[r]=1e9; while(l<r) { int mid=(l+r)>>1; if(f[mid]>=a[i]) r=mid; else l=mid+1; } f[l]=a[i]; if(l==cnt+1) cnt++; if(f[i]>ans) { k=i; ans=f[i]; } } cout<<" max="<<cnt<<endl; dfs(k); return 0; }