알고리즘/DP

[백준] 13398-연속합2(C++)

잉읭응 2020. 9. 6. 18:13
반응형

문제링크:www.acmicpc.net/problem/13398

 

13398번: 연속합 2

첫째 줄에 정수 n(1 ≤ n ≤ 100,000)이 주어지고 둘째 줄에는 n개의 정수로 이루어진 수열이 주어진다. 수는 -1,000보다 크거나 같고, 1,000보다 작거나 같은 정수이다.

www.acmicpc.net

 

쉬운 dp 문제였습니다.

 

조건은 두가지입니다. 

1. 수열에서 수를 하나 제거할 수 있다.

2. 제거하지 않아도 된다.

 

우선 제거하지 않을때는 

if (dp[i - 1][0] > 0)
dp[i][0] = arr[i] + dp[i - 1][0];
else
dp[i][0] = arr[i];

로 쉽게 구할 수 있습니다.

 

그리고 하나의 수를 제거할 때는 

1) 현재 자신을 제거한 값이 큰지,

2) 이전에 제거한 값 + 현재값이 큰지

비교합니다.

 

정답코드입니다.

너무 쉬워서 점화식은 따로 기재하지 않았습니다.

#include <iostream>
#include <algorithm>
using namespace std;

/* 
제거 한경우 제거 안한 경우 

10 -4  3 1 5 6  -35 12 21 -1

0: 10 6 9 10 15 21 -14 -2 19 18   
1: 0 10 13   
현재 자신에서 뺀값이라 이미 빠진값이랑 비교해서 더큰값으로 넣는다. 
*/

int dp[100001][2] = { 0 };
int arr[100001] = { 0 };
int n = 0, result = -1000000000;
int main() {
	cin >> n;
	for (int i = 1; i <= n; i++)
		cin >> arr[i];

	dp[1][0] = arr[1];

	for (int i = 2; i <= n; i++) {
		if (dp[i - 1][0] > 0)
			dp[i][0] = arr[i] + dp[i - 1][0];
		else
			dp[i][0] = arr[i];
	}
	
	dp[1][1] = 0;

	for (int i = 2; i <= n; i++) {
		//1. 자신을 제외했을때 값과 이미 제한값을 비교
		int a = dp[i - 1][0]; //자신을 제외했을때
		int b = dp[i - 1][1] + arr[i];
		dp[i][1] = max(a, b);
	}

	for (int i = 2; i <= n; i++) {
		if (result < dp[i][0]) result = dp[i][0];
		if (result < dp[i][1])	result = dp[i][1];
	}
	if (result < dp[1][0]) result = dp[1][0];




	if (n == 1) cout << arr[1] << endl;
	else cout << result << endl;
	return 0;
}

  

반응형