일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 크루스칼
- 이분탐색
- 백준
- 좌표압축
- 그리디
- 누적합
- 위상정렬
- dfs
- 에라토스테네스의 체
- 정렬
- boj
- 비트마스크
- 구현
- 수학
- 세그먼트트리
- DP
- 다익스트라
- DisjointSet
- LazyPropagation
- lis
- 투포인터
- lca
- 이분매칭
- MST
- 플로이드와샬
- 펜윅트리
- 이진탐색
- 브루트포스
- 삼분탐색
- BFS
Archives
- Today
- Total
lastknight00
[백준]연속합 2(13398) 본문
문제 링크 : [백준]연속합 2(13398)
문제 설명
N개의 수열이 주어질 때, 연속된 구간의 합 중 최대값을 구하세요.
단, 연속합을 구할 때, 하나의 수를 제외하고 연속합을 구할 수 있습니다.
입력
N(수열의 갯수, 1 <= N <= 100,000)
Vi(각 수열의 값, -1,000 <= Vi <= 1,000)
10
10 -4 3 1 5 6 -35 12 21 -1
출력
54
카테고리
#DP
시간 복잡도 상한
O(NlogN)
해결 방법
- 중간에 한개를 빼는 조건이 없다면, 현재 위치로 끝나는 최대 연속합을 구하면 됩니다.
1-1. D[i] = max(D[i-1] + V[i], V[i]) - 그러나 중간에 하나를 뺄 수 있는 경우가 있기 때문에 특별한 조치가 필요합니다.
- DP 배열 하나를 더 만들어야합니다.
- E[i]에다가 오른쪽에서 시작하여 왼쪽으로 진행하면서 i로 끝나는 최대 연속합을 구합니다. 쉽게 말해, D[i]와 반대 방향으로 연속합을 구합니다.
4-1. E[i] = max(E[i+1] + V[i],V[i]) - i를 기준으로, 왼쪽 D값과 오른쪽 E값을 구하여, i를 뺀 왼쪽 오른쪽 연속 구간합들의 최대값을 구합니다.
- answer = for(i=1;i<=N;i++)max(answer, D[i-1] + E[i+1])
- 단, 하나도 안뺴도 되기 때문에, 그 값들에 대한 처리도 해줍니다.
시간복잡도
O(N)
코드
#include<iostream>
#include<algorithm>
#define N 100000
using namespace std;
int n,d[N],e[N],f[N],i,s;
int main(){
ios_base::sync_with_stdio(0);cin.tie(0);
cin>>n;
for(i=0;i<n;i++)cin>>d[i];
e[0]=d[0];f[n-1]=d[n-1];
s=max(e[0],f[n-1]);
for(i=1;i<n;i++){
e[i]=max(e[i-1]+d[i],d[i]);
f[n-i-1]=max(f[n-i]+d[n-i-1],d[n-i-1]);
s=max(s,max(e[i],f[n-i-1]));
}
for(i=1;i<n-1;i++)s=max(s,e[i-1]+f[i+1]);
cout<<s;
}
'PS' 카테고리의 다른 글
[백준]백양로 브레이크(11562) (0) | 2020.07.13 |
---|---|
[백준]36진수(1036) (0) | 2020.07.10 |
[백준]통나무 자르기(1114) (0) | 2020.07.06 |
[백준]한조 대기 중(14433) (0) | 2020.07.05 |
[백준]노트북의 주인을 찾아서(1298) (0) | 2020.07.05 |
Comments