https://www.acmicpc.net/problem/5557
5557번: 1학년
상근이가 1학년 때, 덧셈, 뺄셈을 매우 좋아했다. 상근이는 숫자가 줄 지어있는 것을 보기만 하면, 마지막 두 숫자 사이에 '='을 넣고, 나머지 숫자 사이에는 '+' 또는 '-'를 넣어 등식을 만들며 놀
www.acmicpc.net
코드설명
DP 문제입니다.
처음에는 DFS로 간단하게 실행하여 만약 depth 가 N이라면 종료시키면서 마지막 결과값과 같은경우를 더해주면 될 것이라고 생각했습니다.
하지만, 그렇게할경우 각 선택마다 2배씩 계산횟수가 늘어나게 됩니다. 만약에 10번을 한다면 2^10 으로 1024번.문제에는 100개가 주어져있으니 2^100 의 개수가 나옵니다.
당연히 시간초과가 날 것입니다.
DP[N][21] 을 선언합니다. 여기서 N 부분은 자리수를 의미합니다. 2번째 차원인 21의 의미는 0부터 20까지의 숫자를 의미합니다.
즉, 예로들어보면, 3번째 자리수에서 결과값이 0부터 20까지이니 경우의 수를 메모리제이션 합니다.
그리고 문제에서 주어지듯 마지막 숫자는 결과값입니다.
그러므로, DP[N-2][arr[N-1]] 형식으로 출력하면 마지막 N-1 번째 자리수에서 결과값이 arr[N-1]인 경우의 수가 정답입니다.
코드
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.Arrays; import java.util.StringTokenizer; public class Main { public static int N, M; public static int answer = 0; public static int[] arr; public static void main(String[] args) throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); N = Integer.parseInt(st.nextToken()); arr = new int[N]; long[][] dp = new long[N][21]; //N번째 자리수에서 가능한 등식의 수 개수. st = new StringTokenizer(br.readLine()); for(int i=0;i<N;i++) { arr[i] = Integer.parseInt(st.nextToken()); } dp[0][arr[0]] = 1; for(int i=1; i < N - 1; i++) { for(int num=0; num<=20; num++) { if(dp[i-1][num] > 0) { int plusResult = num + arr[i]; int minusResult = num - arr[i]; if(plusResult >= 0 && plusResult <= 20) { dp[i][plusResult] += dp[i-1][num]; } if(minusResult >= 0 && minusResult <= 20) { dp[i][minusResult] += dp[i-1][num]; } } } } System.out.println(dp[N-2][arr[N - 1]]); } }
'알고리즘 > 백준' 카테고리의 다른 글
[백준] 1915 가장 큰 정사각형 - DP JAVA (0) | 2023.10.29 |
---|---|
[백준] 14567 선수과목 (Prerequisite) - 위상정렬(Topology Sort) JAVA (0) | 2023.10.28 |
[백준] 2011 암호코드 - DP JAVA (0) | 2023.10.26 |
[백준] 2565 전깃줄 - DP + LIS JAVA (0) | 2023.10.25 |
[백준] 2302 극장 좌석 - 동적계획법(DP, Dynamic Programming) + 수학(Math) JAVA (0) | 2023.10.24 |