bzoj1046 [HAOI2007]上升序列——LIS
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1046
倒序求最长下降子序列,则得到了每个点开始的最长上升子序列;
然后贪心输出即可。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int const maxn=10005,inf=0x7fffffff; int n,m,l,a[maxn],b[maxn],len[maxn],cnt; int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); a[b[0]]=inf; for(int i=n;i;i--) { if(a[b[cnt]]>a[i]) { b[++cnt]=i;len[i]=cnt; continue; } int l=1,r=cnt,res; while(l<=r) { int mid=(l+r)/2; if(a[b[mid]]>a[i])l=mid+1; else r=mid-1,res=mid; } b[res]=i;len[i]=res;//i而非a[i]! } scanf("%d",&m); for(int j=1;j<=m;j++) { scanf("%d",&l); if(cnt<l) { printf("Impossible\n");continue; } int nw=-inf; for(int i=1;i<=n;i++) if(len[i]>=l&&a[i]>nw) { printf("%d ",a[i]); nw=a[i];l--; if(!l)break; } printf("\n"); } return 0; }