Processing math: 100%

المپدیا

دانش‌نامه‌ی المپیاد کامپیوتر ایران

ابزار کاربر

ابزار سایت


آموزش:الگوریتم:زیر آرایه با بیشینه ی جمع

زیر‌آرایه با بیشینه‌ی جمع

یکی از مسئله‌های معروف الگوریتم و روش استقرایی، این مسٔله می‌باشد. در زیر به بررسی این مسٔله و روش حل دقیق آن می‌پردازیم.

صورت مسئله

فرض کنید یک آرایه‌ی N عضوی شامل اعداد A1,A2,...,AN داریم به طوری که حداقل یکی از این اعداد مثبت باشد. می‌خواهیم i,j را طوری انتخاب کنیم که حاصل جمع اعداد این بازه، بیشترین مقدار ممکن شود. یعنی مقدار: jk=iAk بیشترین مقدار خود را داشته باشد.

الگوریتم

برای حل این سؤال، آرایه‌ی D را به این صورت تعریف میکنیم:
Di برابر است با مقدار بیشینه‌ی جمع زیر‌آرایه‌ای، که خانه‌انتهایی آن، i باشد.
حال بیایید مقدار Di را به صورت استقرایی بیابیم. D1=A1 است. واضح است که به ازای خانه‌ی ابتدایی، تنها زیر‌آرایه‌ای که به این خانه منتهی می‌شود، زیر‌آرایه متشکل از خود این خانه است. حال به ازای هر i>1 خواهیم داشت: Di=max(Ai,Ai+Di1) زیرا یا زیر‌آرایه‌ی ختم شده به خانه‌ی iام از خانه‌های قبلی استفاده‌ می‌کند، یا استفاده ‌نمی‌کند. که عبارت بالا، هر دوی این حالات را بررسی می‌کند.
اکنون که به ازای هر i، مقدار Di داریم، کافی است بیشترین مقدار Di ها را به دست بیاوریم، تا جواب سؤال را بیابیم.

پیچیدگی‌ الگوریتم

با توجه به الگوریتم استقرایی که ارائه شد، بسیار راحت می‌توان نشان داد که پیچیدگی این الگوریتم از O(N) است.

پیاده‌سازی

maximum_subarray.cpp
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1000 * 1000; // maximum size of array
int A[maxn], D[maxn];
int main() {
    int N;
    cin >> N;
    for(int i=0;i<N;++i)
        cin >> A[i];
 
    D[0] = A[0]; //start of array is 0
    for(int i=1;i<N;++i)
        D[i] = max(D[i - 1] + A[i], A[i]);
 
    int ans = D[0];
    for(int i=1;i<N;++i)
        ans = max(ans, D[i]);
 
    cout << ans << endl;
}

ابزار صفحه