bzoj1046[HAOI2007]上升序列 DP(经典模型)
2017-10-02 14:46
519 查看
题意:给出m个询问,求长度为x字典序最小的上升序列。
倒着做求个lis,然后对于一个x,求出以i开头的,长度大于等于x的上升序列,然后找出排在第一个的(字典序最小),就是答案了。
倒着做求个lis,然后对于一个x,求出以i开头的,长度大于等于x的上升序列,然后找出排在第一个的(字典序最小),就是答案了。
#include<cstdio> #include<algorithm> #include<cstring> #define fo(i,a,b) for(int i=a;i<=b;i++) #define fd(i,a,b) for(int i=a;i>=b;i--) using namespace std; const int N=155; int n,m,tot; int a ,f ,b ; const int inf=1e9; inline void solve(int x) { int last=0; fo(i,1,n) if (f[i]>=x&&a[i]>last) { printf("%d",a[i]); if (x!=1)printf(" "); last=a[i]; x--; if (!x)break; } printf("\n"); } inline int find(int x) { int l=1,r=tot,ans=0; while (l<=r) { int mid=(l+r)>>1; if (b[mid]>x)ans=mid,l=mid+1; else r=mid-1; } return ans; } inline void pre() { fd(i,n,1) { int x=find(a[i]); f[i]=x+1; tot=max(tot,f[i]); if (b[x+1]<a[i])b[x+1]=a[i]; } } int main() { scanf("%d",&n); fo(i,1,n)scanf("%d",&a[i]); pre(); scanf("%d",&m); fo(i,1,m) { int x; scanf("%d",&x); if(x<=tot)solve(x); else printf("Impossible\n"); } return 0; }
相关文章推荐
- BZOJ 1046: [HAOI2007]上升序列 LIS -dp
- [bzoj1046][HAOI2007]上升序列【dp】
- BZOJ 1046 HAOI 2007 上升序列 -- DP 贪心
- 【BZOJ】1046: [HAOI2007]上升序列(dp)
- [BZOJ1046][HAOI2007]上升序列(dp+贪心)
- BZOJ 1046 HAOI 2007 上升序列 DP
- BZOJ 1046 [HAOI2007]上升序列 DP
- bzoj 1046: [HAOI2007]上升序列【dp+二分】
- bzoj 1046 : [HAOI2007]上升序列 dp
- [BZOJ 1046] [HAOI2007] 上升序列 【DP】
- bzoj 1046: [HAOI2007]上升序列 (DP)
- [BZOJ1046] [HAOI2007]上升序列
- BZOJ1046: [HAOI2007]上升序列
- [BZOJ 1046][HAOI 2007]上升序列(nlogn的LIS算法)
- BZOJ 1046: [HAOI2007]上升序列
- BZOJ 1046([HAOI2007]上升序列-LIS二分O(nlogn))
- 【动态规划】【最长上升子序列】【贪心】bzoj1046 [HAOI2007]上升序列
- [bzoj]1046: [HAOI2007]上升序列
- bzoj 1046: [HAOI2007]上升序列
- BZOJ 1046: [HAOI2007]上升序列