NYOJ 214 單調遞增子串行 二

2021-09-08 09:15:52 字數 2311 閱讀 5991

時間限制:

1000 ms  |           記憶體限制:

65535 kb

難度:4 描述

,a2...,an

}(0

輸入有多組測試資料(<=7) 每組測試資料的第一行是乙個整數n表示序列中共有n個整數,隨後的下一行裡有n個整數,表示數列中的所有元素.每個整形數中間用空格間隔開(0輸出

對於每組測試資料輸出整形數列的最長遞增子串行的長度,每個輸出佔一行。

樣例輸入

7

1 9 10 5 11 2 13

22 -1

樣例輸出

5

1

/* **一:  經典求法---tle

#include #include const int n = 100000 + 10;

using namespace std;

int a[n], dp[n];

int main()

}printf("%d\n", maxlen);

}return 0;

}**二:

這是乙個很好的題目。題目的演算法還是比較容易看出來的,就是求最長上公升子串行的長度。

不過這一題的資料規模最大可以達到40000,經典的o(n^2)的動態規劃演算法明顯會超時。

我們需要尋找更好的方法來解決是最長上公升子串行問題。

先回顧經典的o(n^2)的動態規劃演算法,設a[i]表示序列中的第i個數,f[i]表示從1到i這一段

中以i結尾的最長上公升子串行的長度,初始時設f[i] = 0(i = 1, 2, ..., len(a))。則有動態規劃方程:f[i] = max (j = 1, 2, ..., i - 1, 且a[j] < a[i])。

現在,我們仔細考慮計算f[i]時的情況。假設有兩個元素a[x]和a[y],滿足

(1) x < y < i

(2) a[x] < a[y] < a[i]

(3) f[x] = f[y]

此時,選擇f[x]和選擇f[y]都可以得到同樣的f[i]值,那麼,在最長上公升子串行的這個位置中,

應該選擇a[x]還是應該選擇a[y]呢?

很明顯,選擇a[x]比選擇a[y]要好。因為由於條件(2),在a[x+1] ... a[i-1]這一段中,

如果存在a[z],a[x] < a[z] < a[y],則與選擇a[y]相比,將會得到更長的上公升子串行。

再根據條件(3),我們會得到乙個啟示:根據f的值進行分類。對於f的每乙個取值k,

我們只需要保留滿足f[i] = k的所有a[i]中的最小值。設d[k]記錄這個值,

即d[k] = min (f[i] = k)。

注意到d的兩個特點:

(1) d[k]的值是在整個計算過程中是單調不上公升的。

(2) d的值是有序的,即d[1] < d[2] < d[3] < ... < d[n]。

利用d,我們可以得到另外一種計算最長上公升子串行長度的方法。設當前已經求出的

最長上公升子串行長度為len。先判斷a[i]與d[len]。若a[i] > d[len],

則將a[i]接在d[len]後將得到乙個更長的上公升子串行,len = len + 1, d[len] = a[i];

否則,在d[1]..d[len]中,找到最大的j,滿足d[j] < a[i]。令k = j + 1,則有d[j] < a[i] <= d[k],

將a[i]接在d[j]後將得到乙個更長的上公升子串行,同時更新d[k] = a[i]。

最後,len即為所要求的最長上公升子串行的長度。

在上述演算法中,若使用樸素的順序查詢在d[1]..d[len]查詢,由於共有o(n)個元素需要計算,

每次計算時的複雜度是o(n),則整個演算法的時間複雜度為o(n^2),與原來的演算法相比沒有任何進步。

但是由於d的特點(2),我們在d中查詢時,可以使用二分查詢高效地完成,則整個演算法的時間複雜度

下降為o(nlogn),有了非常顯著的提高。需要注意的是,d在演算法結束後記錄的並不是乙個符合題意的

最長上公升子串行!

這個演算法還可以擴充套件到整個最長子序列系列問題,整個演算法的難點在於二分查詢的設計,需要非常小心注意。

*/#include #include const int n = 100000 + 10;

using namespace std;

int a[n], dp[n];

int binarysearch(int k, int len)

return left;

}int main()

printf("%d\n", len);

}return 0;

}

NYOJ 214 單調遞增子串行 二

先開設乙個陣列dp 然後從第乙個數開始列舉,和dp 陣列中的最後乙個元素end 進行比較,如果大於end 直接把這個數接到end 的後面,並且把end 更新為列舉的這個數。如果不大於edn 在dp 陣列中找到第乙個大於這個數的位子 k,並用這個數 替換掉dp k 例如 x 5,dp 則列舉過x 之後...

NYOJ 214 單調遞增子串行 二

單調遞增子串行 二 時間限制 1000 ms 記憶體限制 65535 kb 難度 4 描述 給定一整型數列 0如 1 9 10 5 11 2 13的最長單調遞增子串行是1 9 10 11 13,長度為5。輸入 有多組測試資料 7 每組測試資料的第一行是乙個整數n表示序列中共有n個整數,隨後的下一行裡...

nyoj 214 單調遞增子串行 二

時間限制 1000 ms 記憶體限制 65535 kb 難度 4 描述 給定一整型數列 0 如 1 9 10 5 11 2 13的最長單調遞增子串行是1 9 10 11 13,長度為5。輸入 有多組測試資料 7 每組測試資料的第一行是乙個整數n表示序列中共有n個整數,隨後的下一行裡有n個整數,表示數...