時間限制:
1000 ms | 記憶體限制:
65535 kb
難度:4 描述
,a2...,an
}(0
輸入有多組測試資料(<=7) 每組測試資料的第一行是乙個整數n表示序列中共有n個整數,隨後的下一行裡有n個整數,表示數列中的所有元素.每個整形數中間用空格間隔開(0輸出
對於每組測試資料輸出整形數列的最長遞增子串行的長度,每個輸出佔一行。
樣例輸入
71 9 10 5 11 2 13
22 -1
樣例輸出
51
/* **一: 經典求法---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個整數,表示數...