码迷,mamicode.com
首页 > 其他好文 > 详细

【noi 2.6_1759】最长上升子序列(DP+优化)

时间:2016-09-25 17:18:43      阅读:147      评论:0      收藏:0      [点我收藏+]

标签:

有2种解法:
1.O(n^2) f[i]定义为必选a[i]的答案。
2.O(n log n) 保存扫完前i个选出的答案序列,不断扩大和更新(同位存尽量小的数)这个序列。

代码1——

技术分享
 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 using namespace std;
 6 
 7 const int N=1010;
 8 int a[N],f[N];
 9 
10 int mmax(int x,int y) {return x>y?x:y;}
11 int main()
12 {
13     int n,ans=0;
14     scanf("%d",&n);
15     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
16     for (int i=1;i<=n;i++)
17     {
18       f[i]=1;
19       for (int j=1;j<i;j++)
20         if (a[i]>a[j]) f[i]=mmax(f[i],f[j]+1);
21       ans=mmax(ans,f[i]);
22     }
23     printf("%d",ans);
24     return 0;
25 }
View Code

代码2——

技术分享
 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 using namespace std;
 6 
 7 const int N=1010;
 8 int a[N],f[N];
 9 
10 int ffind(int l,int r,int x)
11 {
12     if (l==r) return l;
13     int mid=(l+r)>>1;
14     if (x>f[mid]) return ffind(mid+1,r,x);
15     else return ffind(l,mid,x);
16 }
17 int main()
18 {
19     int n,ans=0;
20     scanf("%d",&n);
21     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
22     f[++ans]=a[1];
23     for (int i=2;i<=n;i++)
24     {
25       int x;
26       if (a[i]>f[ans]) x=++ans;
27       else x=ffind(1,ans,a[i]);
28       f[x]=a[i];
29     }
30     printf("%d",ans);
31     return 0;
32 }
View Code

【noi 2.6_1759】最长上升子序列(DP+优化)

标签:

原文地址:http://www.cnblogs.com/konjak/p/5906191.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!