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 }
第二种解法(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 }
第二种解法用二分的方法做。
例如样例: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 最长递增子序列的主要内容,如果未能解决你的问题,请参考以下文章