bzoj 1046: [HAOI2007]上升序列【dp+二分】
阿新 • • 發佈:2018-08-04
esp amp const sin ons 第一個 二分 std n)
先從後到前做一個最長下降子序列的dp,記錄f[i],我這裏用的是二分(其實樹狀數組比較顯然)
然後對於詢問,超出最長上升子序列的直接輸出;否則從前到後掃,f[i]>=x&&a[i]>la(上個選的)就選,因為這時第一個出現的一定是符合條件的中最小的最小的
#include<iostream> #include<cstdio> using namespace std; const int N=10005; int n,a[N],m,x,f[N],p[N],cnt,b[N]; int find(int x) { int l=1,r=cnt,ans=0; while(l<=r) { int mid=(l+r)>>1; if(b[mid]>x) l=mid+1,ans=mid; else r=mid-1; } return ans; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=n;i>=1;i--) { int t=find(a[i]); f[i]=t+1; cnt=max(cnt,f[i]); if(b[f[i]]<a[i]) b[f[i]]=a[i]; } scanf("%d",&m); while(m--) { scanf("%d",&x); if(x>cnt) printf("Impossible\n"); else { int la=0; for(int i=1;i<=n&&x;i++) if(f[i]>=x&&a[i]>la) { printf("%d ",a[i]); la=a[i]; x--; } printf("\n"); } } return 0; }
bzoj 1046: [HAOI2007]上升序列【dp+二分】