Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- BOJ 2012
- Lambda
- BOJ 6593
- serverless
- BOJ 2234
- javascript
- BOJ 11726
- BOJ 2407
- DP
- BOJ 4948
- BOJ 2146
- BOJ 2213
- spring security
- BOJ 5791
- 분할과 정복
- 조합 알고리즘
- Coercion
- 다익스트라
- 플로이드 와샬
- springboot
- priority_queue
- BOJ 5568
- BOJ 1912
- AWS
- BOJ 1697
- BOJ 2167
- BOJ 4485
- MySQL
- BOJ 1074
- BOJ 1926
Archives
- Today
- Total
고인물을 지양하는 블로그
BOJ 1912 연속합 본문
https://www.acmicpc.net/problem/1912
1912번: 연속합
첫째 줄에 정수 n(1 ≤ n ≤ 100,000)이 주어지고 둘째 줄에는 n개의 정수로 이루어진 수열이 주어진다. 수는 -1,000보다 크거나 같고, 1,000보다 작거나 같은 정수이다.
www.acmicpc.net
첫 번째 풀이
#include <cstdio>
int main() {
int n;
scanf("%d",&n);
int sum[n], max;
for(int i=0;i<n;++i) {
scanf("%d",&sum[i]);
if(i>0)
sum[i] += sum[i-1];
}
max = sum[0];
for(int i=1;i<n;++i)
for(int j=0;j<i;++j)
if(max < sum[i]-sum[j])
max = sum[i]-sum[j];
printf("%d",max);
}
O(n^2) 알고리즘이다.
sum[i]는 다음과 같이 정의된다
sum[i]: 0~i까지의 누적 합
따라서 sum[i] - sum[j] -> j~i 까지 연속 합이고, 그 중에서 최대를 찾는다.
아슬아슬하게 통과할 줄 알았지만, 시간 초과로 오답이 나왔다.
두 번째 풀이
#include <cstdio>
int main() {
int n;
scanf("%d",&n);
int in[n], dp[n], max;
for(int i=0;i<n;++i)
scanf("%d",&in[i]);
dp[0] = in[0];
max = in[0];
for(int i=1;i<n;++i) {
if(dp[i-1] + in[i] > in[i]) dp[i] = dp[i-1] + in[i];
else dp[i] = in[i];
if(dp[i] > max) max = dp[i];
}
printf("%d",max);
}
O(n) 시간에 수행된다.
dp[i]를 다음과 같이 정의하자
dp[i]: i 까지의 연속합의 최대(local maximum)
위와 같이 정의할 때 점화식은 다음과 같다.
dp[i-1] + a[i]: i-1까지의 연속합과 a[i] 원소를 더한 값이 a[i] 원소보다 작거나 같으면
i.e. 연속한 음수로 a[i]를 더하면 연속 합이 더 작아지기만 하는 경우 혹은 dp[i-1] = 0으로 더해도 의미가 없는 경우, i까지 연속합의 최대를 a[i]로 설정
'Algorithms > ACMICPC(백준)' 카테고리의 다른 글
BOJ 5568 카드 놓기 (0) | 2019.07.26 |
---|---|
BOJ 2167 2차원 배열의 합 (0) | 2019.07.23 |
BOJ 4948 베르트랑 공준 (0) | 2019.07.16 |
BOJ 11726 2 x n 타일링 (0) | 2019.07.15 |
BOJ 5791 거의 최단 경로 (0) | 2019.07.14 |
Comments