题目: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; }
本文解析了一道求解最长上升子序列的问题,通过倒序求最长下降子序列的方法得到每个点开始的最长上升子序列,并使用贪心算法进行输出。文章提供了完整的C++代码实现。
521

被折叠的 条评论
为什么被折叠?



