bzoj1046: [haoi2007]上公升序列
對於乙個給定的s=,若有p=,滿足(x1 < x2 < … < xm)且( ax1 < ax2 < … < axm),那麼就稱p為s的乙個上公升序列。
如果有多個p滿足條件,那麼我們想求字典序最小的那個。
任務給出s序列,給出若干詢問。對於第i個詢問,求出長度為li的上公升序列,如有多個,求出字典序最小的那個(即首先x1最小,如果不唯一,再看x2最小……),如果不存在長度為li的上公升序列,則列印impossible.
第一行乙個n,表示序列一共有n個元素第二行n個數,為a1,a2,…,an 第三行乙個m,表示詢問次數。
下面接m行每行乙個數l,表示要詢問長度為l的上公升序列。n<=10000,m<=1000
對於每個詢問,如果對應的序列存在,則輸出,否則列印impossible.
63 4 1 2 3 636
45impossible
1 2 3 6
impossible
首先要把最長不下降子串行求出來。
設$dp[i]$表示以$i$結尾的最長不下降子串行的長度,$f[i]$表示最長不下降子串行的長度為$i$的最後乙個元素的值。
這個時候用$o(n\log_2n)$的演算法預處理$dp[i]$和$f[i]$。
那,怎麼判斷呢?
我們發現,我們從左到右掃,若存在$dp[i]>=l\&\&a[i]然後就沒了。
附**:
#include#include#include#define maxn 10010using namespace std;
int n,m,s=1;
int a[maxn],b[maxn],f[maxn],dp[maxn];
inline int read()
while(c>='0'&&c<='9')
return date*w;
}int main()
f[1]=b[1];
dp[1]=1;
for(int i=2;i<=n;i++)
f[l]=b[i];
dp[i]=l;
s=max(s,l);
} for(int i=1;i<=n/2;i++)swap(dp[i],dp[n-i+1]);
m=read();
while(m--)
printf("\n");
} return 0;
}
BZOJ 1046 HAOI 上公升序列
1046 haoi2007 上公升序列 time limit 10 sec memory limit 162 mbsubmit 5376 solved 1862 submit status discuss description 對於乙個給定的s 若有p 滿足 x1 x2 xm 且 ax1 2 出s...
bzoj 1046 HAOI2007 上公升序列
首先用f i 表示從i開始的最長上公升子串行的長度 注意這裡和平時的不一樣,是以i開頭而不是以1到i 這就相當於倒序做一遍最長下降子串行 然後要用到貪心 首先假設要取長度為x的,如果比算出來的max大 max正序倒序都一樣的 肯定無解 然後從頭開始取,因為從頭取的下標字典序最小,如果a i 比上乙個...
BZOJ1046 HAOI2007 上公升序列
portal 首先是否存在很容易。考慮如何輸出最小字典序的方案。注意。是位子的字典序,不是值。那麼這樣的話,倒過來做一遍最長下降子串行。f i 表示以 i 開頭的最長上公升子串行長度 找答案的時候就順著找,每次滿足條件就輸出。include include include define n 1000...