1. 程式人生 > >完美世界2016實習生筆試 [程式設計題] 最長遞增子序列A(C++)

完美世界2016實習生筆試 [程式設計題] 最長遞增子序列A(C++)

來源:https://www.nowcoder.com/test/1669710/summary

題目:

給定一個長度為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.



輸出描述:

對於每組資料,輸出一個整數,代表最長遞增子序列的長度。


輸入例子:
2
7
89 256 78 1 46 78 8
5
6 4 8 2 17

輸出例子:
3
3

思路:動態規劃

用一個數組result[]來儲存子問題結果,陣列中每個數值result[i]對應子序列[0~i]的最長上升子序列長度。自底向上,從result[0]開始動態更新到result[n-1],result[i]的值應為result[0]~result[j]中滿足nums[i]>nums[j](j=0~i-1)條件的最大值+1,維護maxLen即為所求。

題解:

#include "iostream"
#include "vector"
using namespace std;
int main()
{
    int repeatT;
    cin>>repeatT;
    while(repeatT--) {
        //輸入資料
        int N;
        cin >> N;
        vector<int> nums;
        for (int i = 0; i < N; i++) {
            int numIn;
            cin >> numIn;
            nums.push_back(numIn);
        }

        int result[3001] = {1};//result[i]表示序列0-i上的最長序列長度

        int maxLen = 1;//維護輸出結果maxLen
        for (int i = 1; i < N; i++) {
            if (result[i] == 0)   //初始化result陣列
                result[i] = 1;
            //更新
            for (int j = 0; j < i; j++)  //從前向後掃描以[i-1]為尾部的陣列,動態更新result[j](j從0到i-1)值
            {
                if (nums[i] > nums[j]) {
                    if ((result[j] + 1) > result[i])
                        result[i] = result[j] + 1;
                    if (result[j] + 1 > maxLen)
                        maxLen = result[j + 1];
                }
            }
//        for(int j=0;j<N;j++)
//            cout<<result[j];
//        cout<<endl;
        }
        cout << maxLen<<endl;
    }
    return 0;
}