51 nod 1134 最长递增子序列

Posted fjqfjq

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51 nod 1134 最长递增子序列相关的知识,希望对你有一定的参考价值。

第一种解法(超时)

技术分享图片
 1 #include <iostream>
 2 using namespace std;
 3 #define ll long long
 4 ll a[500005];
 5 int dp[500005];
 6 
 7 int main()
 8 {
 9     int n;
10     cin>>n;
11     for(int i=1;i<=n;i++){
12         cin>>a[i];
13     }
14     int maxn=0;
15     for(int i=1;i<=n;i++){
16         for(int j=1;j<i;j++){
17             if(a[i]>a[j])
18                 dp[i]=max(dp[i],dp[j]+1);
19         }
20         maxn=max(maxn,dp[i]);
21     }
22 //    for(int i=1;i<=n;i++){
23 //        cout<<dp[i]<<" ";
24 //    }
25 //    cout<<endl;
26     cout<<maxn+1<<endl;
27     return 0;
28 }
View Code

第二种解法(AC)

技术分享图片
 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 #define ll long long
 5 ll a[500005];
 6 ll dp[500005];
 7 
 8 int main()
 9 {
10     int n;
11     cin>>n;
12     for(int i=0;i<n;i++){
13         cin>>a[i];
14     }
15     int len=0;
16     dp[0]=-99999999999;
17     for(int i=0;i<n;i++){
18         if(a[i]>dp[len]){
19             dp[++len]=a[i];
20         }
21         else{
22             int pos=lower_bound(dp+1,dp+len,a[i])-dp;
23             if(a[i]<dp[pos]){
24                 dp[pos]=a[i];
25             }
26         }
27     }
28     cout<<len<<endl;
29     return 0;
30 }
View Code

第二种解法用二分的方法做。

例如样例:5 1 6 8 2 4 5 10

首先,dp[0]=5,然后对于1的时候,因为1<5,把dp[0]替换成1。

然后因为1<6 , 6<8,依次把6 8放入dp数组,此时的dp:1 6 8,长度为3。

当2的时候,用二分查找在dp中>=2的位置(dp数组本来就是从小到大排列的,所以可以使用lower_bound(),lower_bound()的使用必须要是有序的数组),如果查找出来的位置在dp数组里面,那么把该位置的数字改为2,即把6替换成2,此时dp[1]=2。

依次上面操作,得到最终的dp:1 2 4 5 10 ,长度为5。

当你把dp里面的数字替换的时候,因为替换的数字更小,所以可以保证最优解,而且替换的时候数组的长度是不变的,所以可行。

以上是关于51 nod 1134 最长递增子序列的主要内容,如果未能解决你的问题,请参考以下文章

51nod 1134 最长递增子序列

51Nod 1134 最长递增子序列

51nod 1134 最长递增子序列 (O(nlogn)算法)

LCS 51Nod 1134 最长递增子序列

51nod1134(最长递增子序列)

51 nod 1134 最长递增子序列