日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

BZOJ 1046: [HAOI2007]上升序列【贪心+二分状态+dp+递归】

發布時間:2025/3/8 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ 1046: [HAOI2007]上升序列【贪心+二分状态+dp+递归】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1046: [HAOI2007]上升序列

Time Limit: 10 Sec??Memory Limit: 162 MB
Submit: 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

6
3 4 1 2 3 6
3
6
4
5

Sample Output

Impossible
1 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+递归】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。