8
1 2 5 7 3 4 6 8
复杂度 o(n^2)
#include<bits/stdc++.h>
using namespace std;
int a[100];
int dp[100];
int32_t main()
{
int n; cin>>n;
for(int i=1;i<=n;i++) { cin>>a[i]; dp[i]=1;}
for(int i=1;i<=n;i++)
{
for(int j=1;j<i;j++)
{
if(a[i]>a[j])
{
dp[i]=max(dp[i],dp[j]+1);
}
}
}
int ans=0;
for(int i=1;i<=n;i++) ans=max(ans,dp[i]);
cout<<ans<<endl;
}
优化; o(nlogn)
方法一 二分+贪心
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+10; const int INF=0x3f3f3f3f; int a[100]; int low[100]; int32_t main() { int n; cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; low[i]=INF;} low[1]=a[1]; int ans=1; for(int i=2;i<=n;i++) { if(low[ans]<a[i]) { low[++ans]=a[i]; } else { int k=lower_bound(low+1,low+ans,a[i])-low; low[k]=a[i]; } } // for(int i=1;i<=ans;i++) cout<<low[i]<<" "; cout<<endl; cout<<ans<<endl; }
用low_lound的情况少 一般题目不会让你直接用low_bound;
方法二 dp+ 树状数组;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+10; const int INF=0x3f3f3f3f; int n; int T[maxn]; struct person { int val; int num; }node[maxn]; bool comp(person a,person b) { if(a.val!=b.val) return a.val<b.val; return a.num<b.num; } void modify(int x,int y) //把val[x]替换为val[x]和y中较大的数 { for(;x<=n;x+=x&(-x)) T[x]=max(T[x],y); } int query(int x) //返回val[1]~val[x]中的最大值 { int res=-INF; for(;x;x-=x&(-x)) res=max(res,T[x]); return res; } int32_t main() { cin>>n; for(int i=1;i<=n;i++) { cin>>node[i].val; node[i].num=i;} sort(node+1,node+1+n,comp); int ans=0; for(int i=1;i<=n;i++) { int t=query(node[i].num); modify(node[i].num,++t); ans=max(ans,t); } cout<<ans<<endl; return 0; }
洛古p1091
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; const int maxn=1e2+5; int n; int a[maxn]; int row[maxn]; int low[maxn]; int divid(int x) { memset(low,0,sizeof(low)); memset(row,0,sizeof(row)); int ans1=1; low[ans1]=a[x]; for(int i=x-1;i>=1;i--) { if(a[i]<low[ans1]) { low[++ans1]=a[i]; } else if(a[i]>=a[x]) continue; else if(a[i]==low[ans1]) continue; else if(a[i]>low[ans1] && a[i]<a[x] ) { for(int j=1;j<ans1;j++)// o(n^2); { if(low[j]>a[i]&&a[i]>=low[j+1]) { low[j+1]=a[i]; break; } } } } int ans2=1; row[ans2]=a[x]; for(int i=x+1;i<=n;i++) { // cout<<ans2<<endl if(a[i]<row[ans2]) { row[++ans2]=a[i]; } else if(a[i]>=a[x]) continue; else if(a[i]==row[ans2]) continue; else { //cout<<a[i]<<endl; for(int j=1;j<ans2;j++) { if(row[j]>a[i]&&a[i]>=row[j+1]) { row[j+1]=a[i]; } } } } // cout<<" "<<ans1<<" "<<ans2<<endl; // for(int i=1;i<=ans1;i++) cout<<low[i]<<" "; cout<<endl; // for(int i=1;i<=ans2;i++) cout<<row[i]<<" "; cout<<endl; int ans=ans1+ans2; return ans; } int32_t main() { cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; int maxlong=0; for(int i=1;i<=n;i++) { int k=divid(i); k=k-1; //cout<<k<<endl; maxlong=max(k,maxlong); } cout<<n-maxlong<<endl; }