In computer science, the maximum subarray problem is the task of finding the contiguous subarray within a one-dimensional array of numbers which has the largest sum. For example, for the sequence of values −2, 1, −3, 4, −1, 2, 1, −5, 4; the contiguous subarray with the largest sum is 4, −1, 2, 1, with sum 6.
The problem was first posed by Ulf Grenander of Brown University in 1977, as a simplified model for maximum likelihood estimation of patterns in digitized images. A linear time algorithm was found soon afterwards by Jay Kadane of Carnegie-Mellon University (Bentley 1984).
출처: https://en.wikipedia.org/wiki/Maximum_subarray_problem
분할 정복과 동적 계획법을 공부할 수 있는 Maximum subarray problem (최대 구간 합 문제) 입니다.
분할 정복 풀이법은 배열을 절반으로 나눠서 좌측 부분의 최대합과 우측 부분의 최대합의 합과 그리고 정답(최대합)의 배열이 (좌측이나 우측) 한 쪽에서 시작해서 한 쪽에서 끝날 가능성을 고려하여 3가지 경우 중 최대값을 구하는 방법입니다.
동적 계획 풀이법은 동적 계획법답게 중복해서 최소값을 구하는 부분 즉 계산할 필요가 없는 부분을 건너뛰어 (계산 결과를 재활용함으로써) 시간 복잡도를 줄이고 있습니다.
c++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | #include <iostream> #include <fstream> #include <string> #include <algorithm> #include <vector> #include <ctime> using namespace std; vector<int> numbers; int N; int bruteForce() { int ret = INT_MIN; for (int i = 0; i < N; i++) { int sum = 0; for (int j = i; j < N; j++) { sum += numbers[j]; ret = max(ret, sum); } } return ret; } int divideAndConquer(int left, int right) { if (left == right) return numbers[left]; int leftMaxSum = INT_MIN; int rightMaxSum = INT_MIN; int middle = (left + right) / 2; int tempSum = 0; for (int i = middle; i >= left; i--) { tempSum += numbers[i]; leftMaxSum = max(leftMaxSum, tempSum); } tempSum = 0; for (int i = middle + 1; i <= right; i++) { tempSum += numbers[i]; rightMaxSum = max(rightMaxSum, tempSum); } int dividedMaxSum = max(divideAndConquer(left, middle), divideAndConquer(middle + 1, right)); return max(leftMaxSum + rightMaxSum, dividedMaxSum); } //Kadane's algorithm int dynamicProgramming() { int ret = INT_MIN; int partialSum = 0; for (int i = 0; i < N; i++) { partialSum = max(partialSum, 0) + numbers[i]; ret = max(partialSum, ret); } return ret; } int main() { //8000 numbers ifstream fin("input.in"); int a; while (fin >> a) { numbers.push_back(a); } N = numbers.size(); clock_t start = clock(); cout << "bruteForce : " << bruteForce() << " elapse time : "; clock_t end = clock(); double time = double(end - start) / CLOCKS_PER_SEC; cout << time << endl; start = clock(); cout << "divideAndConquer : " << divideAndConquer(0, N - 1) << " elapse time : "; end = clock(); time = double(end - start) / CLOCKS_PER_SEC; cout << time << endl; start = clock(); cout << "dynamicProgramming : " << dynamicProgramming() << " elapse time : "; end = clock(); time = double(end - start) / CLOCKS_PER_SEC; cout << time << endl; system("pause"); return 0; } | cs |
bruteForce : 1646 elapse time : 11.554
divideAndConquer : 1646 elapse time : 0.041
dynamicProgramming : 1646 elapse time : 0.004
'Algorithm, Data structure > Popular Algorithms' 카테고리의 다른 글
karatsuba algorithm (0) | 2016.06.21 |
---|---|
Travelling salesman problem (0) | 2016.06.05 |