Hướng dẫn cho Tổng dãy con


Chỉ sử dụng khi thực sự cần thiết như một cách tôn trọng tác giả và người viết hướng dẫn này.

Chép code từ bài hướng dẫn để nộp bài là hành vi có thể dẫn đến khóa tài khoản.

Authors: SPyofgame


Spoiler Alert


Hint 1

  • Tìm dãy con có tổng lớn nhất

Ý tưởng cơ bản: Thử tất cả các dãy \(a_i, a_j, ...\) và tìm dãy có tổng lớn nhất

  • Tìm đoạn con có tổng lớn nhất

Ý tưởng cơ bản: Thử tất các các đoạn \((i, j)\)\((i \leq j)\) và tìm đoạn có tổng lớn nhất


Hint 2

  • Tìm dãy con tổng lớn nhất

Gọi \(sum1\) là tổng ở hiện tại

Nhận xét rằng \(sum1 + x < sum1\) khi \(x < 0\)

Nhận xét rằng \(sum1 + x \geq sum1\) khi \(x \geq 0\)

  • Tìm đoạn con có tổng lớn nhất

Gọi \(curr\) là giá trị lớn nhất đến hiện tại

Gọi \(sum2\) lá giá trị cực đại của \(curr\)

Nhận xét rằng \(curr + x < x\) khi \(curr < 0\)

Nhận xét rằng \(curr + x \geq x\) khi \(curr \geq 0\)


Hint 3

  • Tìm dãy con tổng lớn nhất

Trong trường hợp mảng chí toàn âm: Ta tìm số âm lớn nhất

Trong trường hợp mảng có số không âm: Ta tính tổng tất cả các số không âm

  • Tìm đoạn con có tổng lớn nhất

Trong trường hợp \(curr\) âm, ta thay \(curr = x\)

Trong trường hợp \(curr\) dương, ta thêm \(curr\) đại lượng \(x\)

\(sum2 = max(curr)\) tại mọi thời điểm


Hint 4

  • Tìm dãy con tổng lớn nhất

\(sum1 = max(sum1, max(sum1 + temp, temp));\)

  • Tìm đoạn con có tổng lớn nhất [Kadane Algorithm]

\(curr = max(temp, curr + temp);\)

\(sum2 = max(sum2, curr);\)


Reference AC code | \(O(n)\) time | \(O(1)\) auxiliary space | Online Solving, Greedy, DP

C++
int query()
{
    int sum1 = -INF;
    int sum2 = -INF, curr = 0;
    for (int n = readInt(); n--; ) {
        int temp;
        cin >> temp;
        sum1 = max(sum1, max(sum1 + temp, temp));
        curr = max(temp, curr + temp);
        sum2 = max(sum2, curr);
    }

    cout << sum1 << ' ' << sum2 << '\n';
    return 0;
}


Bình luận

Không có bình luận nào.