1. 문제

https://www.acmicpc.net/problem/5557

 

5557번: 1학년

상근이가 1학년 때, 덧셈, 뺄셈을 매우 좋아했다. 상근이는 숫자가 줄 지어있는 것을 보기만 하면, 마지막 두 숫자 사이에 '='을 넣고, 나머지 숫자 사이에는 '+' 또는 '-'를 넣어 등식을 만들며 놀

www.acmicpc.net

2. 접근방법

등식의 갯수가 2^63-1개(long) 까지 가능하다고 한다.

완탐으론 불가능하고 dp를 이용해야 한다.

 

dp로 풀이하기 편하도록 하나의 장치가 있다.

상근이가 아는 숫자가 0부터 20까지 뿐이라 이 밖의 숫자가 중간 연산 중에 나오면 무시된다.는 조건이다.

 

연산에서 나올 수 있는 수를 20까지만 고려하면 되니 dp로 풀이가 가능한 것이다.

 

점화식으로

이번 숫자(arr[i])에 + - 를 해서 0~20을 만들 수 있는 경우의 수를 구하면된다.

dp 배열로 보면 아래와 같이 되고

        0 1 2 .... 19 20

arr[0]

arr[1]

arr[2]

...

arr[N]

 

arr[0]의 경우 -를 넣으면 음수가 되니 arr[0]인 수 하나만 가능하고

 

그 다음 부터인 arr[1]부터는

dp[1][0] = dp[0][0 - arr[1]] + dp[0][0 + arr[1]]

dp[1][1] = dp[0][1 - arr[1]] + dp[0][1 + arr[1]]

...

dp[1][20] = dp[0][1-arr[20]] + dp[0][1+arr[20]]

이런 식이 될 것이다.

 

예를 들어 이번 수가 3일 때

dp[i][15]의 갯수는 12+3 = 15 , 18 - 3 = 15 이므로

이전 연산까지 만들어진 12와 18의 갯수를 더한 값이 되는 것이다.

 

설명이 조금 복잡한데 코드로 보면 간단하다.

3. 자바 코드

package Gold;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;

public class G5_5557a1학년 {
	
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int N = Integer.parseInt(br.readLine());
		int arr [] = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
		long dp[][] = new long[N][21];
		dp[0][arr[0]]++;
		for(int i = 1 ; i < N -1 ; i++) {
			int num = arr[i];
			for(int j = 0 ; j<21 ; j++ ) {
				if(j-num >= 0)
					dp[i][j]+=dp[i-1][j-num];
				if(j+num <21)
					dp[i][j]+=dp[i-1][j+num];
			}
		}
		System.out.println(dp[N-2][arr[N-1]]);
	}
}

4. 마치며

20 조건을 생각못하고 이걸 어떻게 풀지 하고 삽질을 많이 했다..

 

 

'알고리즘 문제풀이 > 백준' 카테고리의 다른 글

[백준] 1715 카드 정렬하기  (0) 2021.11.26
[백준] 2631 줄세우기  (0) 2021.11.25
[백준] 1726 로봇  (0) 2021.11.20
[백준] 9084 동전  (0) 2021.11.09
[백준] 11000 강의실 배정  (0) 2021.11.04

+ Recent posts