DCTDN2 - Dãy con tăng dài nhất (Bản TB)

Xem dạng PDF

Gửi bài giải

Điểm: 2,00 (OI)
Giới hạn thời gian: 1.0s
Giới hạn bộ nhớ: 256M

Tác giả:
Dạng bài
Ngôn ngữ cho phép
C, C#, C++, Go, Java, Pascal, Perl, PHP, Python, Ruby, Rust, Scratch, Swift

Cho một dãy số nguyên gồm ~N~ phần tử ~a_1, a_2, …, a_N~. Một dãy con đơn điệu tăng của dãy trên là dãy ~a_{i_1}, a_{i_2}, …, a_{i_k}~ sao cho: ~i_1 < i_2 < … < i_k~ và ~a_{i_1} < a_{i_2} < … < a_{i_k}~. Hãy cho biết dãy con đơn điệu tăng của dãy đã cho có nhiều nhất bao nhiêu số hạng?

Input

  • Dòng đầu chứa số nguyên dương ~N~;
  • Dòng thứ hai chứa ~N~ số nguyên dương ~a_1, a_2, …, a_N~, mỗi số cách nhau bởi một dấu cách.

Giới hạn:

  • ~1 ≤ n ≤ 10^5, 1 ≤ a_i ≤ 10^6~

Output

  • Ghi ra độ dài của dãy con đơn điệu tăng dài nhất.

Sample

Input #1
6
1 2 5 4 6 2
Output #1
4

Hint

  • Dãy con tăng dài nhất là dãy ~1, 2, 4, 6~ độ dài dãy này là ~4~.

Problem source: Chuyên Sơn La Online Judge


Bình luận

Hãy đọc nội quy trước khi bình luận.



  • 17
    tri_88  đã bình luận lúc 8, Tháng 1, 2024, 8:26

    Đầu tiên nhập vào một số n.

    Khi nào n > 0.

    Thì nhập vào 1 số a.

    Tiếp theo dùng hàm lower_bound() để tìm m là vị trí phần tử đầu tiên trong multiset có giá trị lớn hơn hoặc bằng với a

    Sau khi dùng hàm lower_bound() xong các bạn phải cộng thêm 1 vì vị trí m trong multiset thực tế là m+1.

    Rồi kiểm tra xem nều m != multiset.end() thì xoá m đi.

    (Nếu như m != multiset.end() thì xoá đi để tìm 1 vị trí khác thoả mãn)

    Thì kích thước của multiset sẽ là kết quả của bài.

    Code mẫu (C++) tại Đây


  • 0
    ChauCao  đã bình luận lúc 12, Tháng 12, 2023, 11:24

    include <iostream>

    include <vector>

    include <algorithm>

    using namespace std;

    int binarySearch(const vector<int>& tails, int key, int end) { int start = 0; while (start < end) { int mid = start + (end - start) / 2; if (tails[mid] >= key) { end = mid; } else { start = mid + 1; } } return start; }

    int longestIncreasingSubsequence(const vector<int>& a) { int n = a.size(); if (n == 0) return 0;

    vector<int> tails(n, 0);
    int length = 1;
    tails[0] = a[0];
    
    for (int i = 1; i < n; ++i) {
        if (a[i] < tails[0]) {
            // Smallest element encountered so far
            tails[0] = a[i];
        } else if (a[i] > tails[length - 1]) {
            // Largest element encountered so far
            tails[length++] = a[i];
        } else {
            // Element is somewhere in between, use binary search to find the correct position
            int pos = binarySearch(tails, a[i], length - 1);
            tails[pos] = a[i];
        }
    }
    
    return length;
    

    }

    int main() { int n; cin >> n; vector<int> a(n); for (int i = 0; i < n; ++i) cin >> a[i];

    int result = longestIncreasingSubsequence(a);
    
    cout << result << endl;
    
    return 0;
    

    }