1153 選擇子串行
codility
基準時間限制:1 秒 空間限制:131072 kb 分值: 40
難度:4級演算法題
長度為n的整數陣列a,所有的數均不相同,假設下標從0開始。找到乙個最長的陣列b,b陣列的長度為k,數值範圍是0 - n - 1,記錄的是a陣列的下標。滿足a[b[0]] > a[b[1]] > a[b[2]] >...a[b[k]],並且對任意連續的兩項b[i]及b[i + 1],滿足min(b[i],b[i + 1]) < j < max(b[i],b[i + 1]) 均有a[j] < a[b[i + 1]] ,求最大的k。例如:9, 10, 2, -1, 3, -5, 0, -3, 1, 12, 5, 8, -2, 6, 4。可以選出:12, 10, 3, 1, 0, -3。對應的下標為:9, 1, 4, 8, 6, 7(就是b陣列),輸出6。
input
第1行:乙個數n,表示a陣列的長度。(1 <= n <= 50000)input示例第2 - n + 1行:每行1個數對應a陣列的元素ai(0 output
輸出b陣列最長的長度k。
15910output示例2-13-5
0-3112
58-26
4
6
李陶冶(題目提供者)
c++ 11的執行時限為:1000 ms ,空間限制為:131072 kb
示例及語言說明請按這裡
題意:找乙個下降序列,要求相鄰的兩位滿足題目的要求。
思路:顯然,b陣列第乙個數是a陣列的最大數下標,假如不是,將此下標放到b陣列首位可以獲得更優解。因此得出如下簡單分治方法o(nlogn),為什麼不會超時呢?因為資料弱,沒有單調遞減的樣例,並不會退化到o(n*n)。那如果資料加強了怎麼辦呢?顯然可以用線段樹或其他辦法預處理出區間的最大值,遞迴時就無需每次都遍歷了。另外的方法就是單調棧,我們預處理每個數左右最近的比自己大的數的下標l[i]和r[i],留意到遞迴過程找到的分界點下標,i必然就是l[i]的右界和r[i]的左界,因此o(n)可以解決本題。
ac_1:
# include using namespace std;
const int maxn = 5e4+30;
int h[maxn];
int solve(int l, int r)
int main()
printf("%d\n",solve(1, n, id));
return 0;
}
51nod 1153 選擇子串行(單調佇列)
題目 長度為n的整數陣列a,所有的數均不相同,假設下標從0開始。找到乙個最長的陣列b,b陣列的長度為k,數值範圍是0 n 1,記錄的是a陣列的下標。滿足a b 0 a b 1 a b 2 a b k 並且對任意連續的兩項b i 及b i 1 滿足min b i b i 1 j max b i b i...
51NOD 最長公共子串行問題
給出兩個字串a b,求a與b的最長公共子串行 子串行不要求是連續的 比如兩個串為 abcicba abdkscab ab是兩個串的子串行,abc也是,abca也是,其中abca是這兩個字串最長的子串行。輸入 第1行 字串a 第2行 字串b a,b的長度 1000 輸出 輸出最長的子串行,如果有多個,...
51NOD 最長公共子串行問題
最長公共子串行問題就是求序列a a1,a2,an,和b b1,b2,bm,的乙個最長公共子串行。因為最長公共子串行不唯一,讓我們把問題簡化,如何求出兩個序列的最長公共子串行長度呢?你首先能想到的恐怕是暴力列舉?那我們先來看看 序列a有 2 n 個子序列,序列b有 2 m 個子序列,如果任意兩個子串行...