題目:
給定一個長度為N的數組,找出一個最長的單調自增子序列(不一定連續,但是順序不能亂)
例如:給定一個長度為8的數組A{1,3,5,2,4,6,7,8},則其最長的單調遞增子序列為{1,2,4,6,7,8},長度為6.
輸入描述:
第一行包含一個整數T,代表測試數據組數。
對於每組測試數據:
N-數組的長度
a1 a2 ... an (需要計算的數組)
保證:
1<=N<=3000,0<=ai<=MAX_INT.
輸出描述:
對於每組數據,輸出一個整數序列,代表最長遞增子序列。
若有多組最長上升子序列,輸出第一組。
保證:1<=T<=20,1<=N<=3000,0<=ai<=MAX_INT.
輸入例子:
2 7 89 256 78 1 46 78 8 5 6 4 8 2 17
輸出例子:
1 46 78 6 8 17
思路:
上一道題是輸出最長遞增子序列的長度,而這一道是要求輸出序列。只要再維護一個pos數組,保存第i個數的上一個序列內數的位置即可。例如序列5 1 6 50 9 12,第4
個數9的上一個序列數為6, 下標為3,那么pos[4] = 3
代碼:
1 #include <iostream> 2 #include <algorithm> 3 #include <vector> 4 using namespace std; 5 6 vector<int> getMaxSub(vector<int> v) 7 { 8 int size = v.size(); 9 vector<int> len(size,1); 10 vector<int> pos(size);//記錄位置 11 //res[i]代表以第i個元素結尾的長度 12 for (int i = 0; i < size; ++i) 13 { 14 for (int j = 0; j < i; ++j) 15 { 16 if (v[j] < v[i] && len[i] < len[j] + 1) 17 { 18 len[i] = len[j] + 1; 19 pos[i] = j; 20 } 21 } 22 } 23 24 int max = -1; 25 int lastPos = -1; 26 for (int i = 0; i < len.size(); ++i) 27 { 28 if (max < len[i]) 29 { 30 max = len[i]; 31 lastPos = i; 32 } 33 } 34 35 vector<int> res; 36 for (int i = 0; i < max; ++i) 37 { 38 res.push_back(v[lastPos]); 39 lastPos = pos[lastPos]; 40 } 41 reverse(res.begin(), res.end()); 42 43 return res; 44 } 45 46 int main() 47 { 48 int T; 49 cin >> T; 50 vector<int> v; 51 while (T--) 52 { 53 int size; 54 cin >> size; 55 int temp; 56 for (int i = 0; i < size; ++i) 57 { 58 cin >> temp; 59 v.push_back(temp); 60 } 61 auto ans = getMaxSub(v); 62 63 for (int i = 0; i < ans.size() - 1;++i) 64 { 65 cout << ans[i] << ' '; 66 } 67 cout << ans[ans.size() - 1] << endl; 68 v.clear(); 69 } 70 return 0; 71 }