BZOJ 1046: [HAOI2007]上升序列【贪心+二分状态+dp+递归】
1046: [HAOI2007]上升序列
Time Limit: 10 Sec??Memory Limit: 162 MBSubmit: 4987??Solved: 1732
[Submit][Status][Discuss]
Description
對于一個給定的S={a1,a2,a3,…,an},若有P={ax1,ax2,ax3,…,axm},滿足(x1 < x2 < … < xm)且( ax1 < ax
2 < … < axm)。那么就稱P為S的一個上升序列。如果有多個P滿足條件,那么我們想求字典序最小的那個。任務給
出S序列,給出若干詢問。對于第i個詢問,求出長度為Li的上升序列,如有多個,求出字典序最小的那個(即首先
x1最小,如果不唯一,再看x2最小……),如果不存在長度為Li的上升序列,則打印Impossible.
Input
第一行一個N,表示序列一共有N個元素第二行N個數,為a1,a2,…,an 第三行一個M,表示詢問次數。下面接M
行每行一個數L,表示要詢問長度為L的上升序列。N<=10000,M<=1000
Output
對于每個詢問,如果對應的序列存在,則輸出,否則打印Impossible.
Sample Input
63 4 1 2 3 6
3
6
4
5
Sample Output
Impossible1 2 3 6
Impossible
HINT
Source
題目鏈接:http://www.lydsy.com/JudgeOnline/problem.php?id=1046
分析:首先求出以每個數為開頭上升序列長度,即倒著做最長下降子序列
然后,把字典序盡量小的放前面
即若要求的序列長度為x,如果以第一個數(字典序最小的數)開頭的最長上升子序列大等于x,則將它放在答案第一個,第二個數開頭小于x,則舍棄,第三個大于x-1,放答案第二個,以此類推!
下面給出AC代碼:
1 #include <bits/stdc++.h> 2 using namespace std; 3 inline int read() 4 { 5 int x=0,f=1; 6 char ch=getchar(); 7 while(ch<'0'||ch>'9') 8 { 9 if(ch=='-') 10 f=-1; 11 ch=getchar(); 12 } 13 while(ch>='0'&&ch<='9') 14 { 15 x=x*10+ch-'0'; 16 ch=getchar(); 17 } 18 return x*f; 19 } 20 int n,m,cnt; 21 const int N=100010; 22 int a[N],f[N],best[N]; 23 inline void solve(int x) 24 { 25 int last=0; 26 for(int i=1;i<=n;i++) 27 { 28 if(f[i]>=x&&a[i]>last) 29 { 30 printf("%d",a[i]); 31 if(x!=1) 32 printf(" "); 33 last=a[i]; 34 if(!(--x)) 35 break; 36 } 37 } 38 printf("\n"); 39 } 40 inline int find(int x) 41 { 42 int l=1,r=cnt,ans=0; 43 while(l<=r) 44 { 45 int mid=(l+r)/2; 46 if(best[mid]>x) 47 ans=mid,l=mid+1; 48 else 49 r=mid-1; 50 } 51 return ans; 52 } 53 inline void pre() 54 { 55 for(int i=n;i;i--) 56 { 57 int t=find(a[i]); 58 f[i]=t+1; 59 cnt=max(cnt,t+1); 60 if(best[t+1]<a[i]) 61 best[t+1]=a[i]; 62 } 63 } 64 int main() 65 { 66 n=read(); 67 for(int i=1;i<=n;i++) 68 a[i]=read(); 69 pre(); 70 m=read(); 71 for(int i=1;i<=m;i++) 72 { 73 int x=read(); 74 if(x<=cnt) 75 solve(x); 76 else 77 printf("Impossible\n"); 78 } 79 return 0; 80 }?
轉載于:https://www.cnblogs.com/ECJTUACM-873284962/p/7305142.html
總結
以上是生活随笔為你收集整理的BZOJ 1046: [HAOI2007]上升序列【贪心+二分状态+dp+递归】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【.net 深呼吸】自定义应用程序配置节
- 下一篇: 黑客教父龚蔚演讲:钓鱼WiFi 也能照用