어떤 수열이 있을 때 연속된 구간의 최대합을 출력하려고 한다.
예를 들어
2 -6 4 5 -2 6 2 -1이라는 수열이 있다면
연속된 구간의 최대 부분합은 15이다. (4+5+ -2 + 6 + 2)
입력
첫째줄에 수열의 원소의 개수 n이 입력된다. (1 <= n <= 100,000)
둘째 줄에 n개의 정수 원소 값이 차례대로 입력된다. (값의 범위: -100 ~ + 100)
출력
연속된 구간의 최대합을 출력한다.
입력 예시
8 2 -6 4 5 -2 6 2 -1
출력 예시
15
일단 입력이 10만개라서... 2차원 배열은 못했구요
그래서..
#include<iostream>
using namespace std;
int data[100001] = { 0, };
int main() {
int N = 0, before = 0, big = 0;
cin >> N;
for (int i = 0; i < N; i++)
cin >> data[i];
before = data[0];
for (int i = 0; i < N-1; i++) {
before = data[i];
for (int j = i + 1; j < N; j++){
before = before + data[j];
if (before >= big)
big = before;
}
}
cout << big << endl;
return 0;
}
이렇게 풀었는데... (피보나치 수열 풀듯이... )
그런데 시간초과가 나더라구요...
접근은 어떻게 해야될까요??
(DP 로 접근해주세요)
도와주십쇼
O(n) 또는 O(nlogn)으로 어떻게 구해야되는지 그게 몰라서요ㅠㅠㅠ 다이나믹 프로그래밍 문제인건확실합니다
http://gall.dcinside.com/board/view/?id=programming&no=469417
간단하게 그냥 +구간은 +대로 -구간은 -대로 나눠서 +구간 사이에 -구간 값을 계산해서 최대값 구하면 될 것 같은데?
2 -6 4 5 -2 6 2 -1 이거 같은경우에는 2 -6 9 -2 8 -1 로 요약되는데 이걸 나눠서 +구간 사이에있는 -가 +랑 서로 비교해서 크면 중간에 씹고 더해주는 식으로 가면 나올듯
꼭 DP로 풀어야 하는건 아닌데 ㅇㅇ sum of subset으로 검색해봐라 많이 나온다
아래쪽 입력예시에 대한 답 19아님?
맨앞에 8 은 원소의 갯수임.
차례로 더해가면서 최소값이 나오는 구간을 시작으로 잡고 최대값이 나오는지점을 끝으로 잡아
int getMax(int begin,int end){ int ret1,ret2,max=0; int middle=(begin+end)/2; if((end-begin)<=1) return arr[begin]+arr[end]; ret1=getMax(begin,middle); ret2=getMax(middle+1,end); max=maxNum(ret1,ret2,ret1+ret2); return max;}