Search

[SWEA] 2817. 부분 수열의 합

서론

오늘은 SW Expert Academy에서 D3 문제를 골랐습니다. 정답률이 낮아서 좀 어려울 것 같습니다.

문제 분석

문제의 요구사항은 다음과 같습니다.
A1, A2, ... , AN의 N개의 자연수가 주어졌을 때, 최소 1개 이상의 수를 선택하여 그 합이 K가 되는 경우의 수를 구하는 프로그램을 작성하는 것입니다.
입력으로는 테스트 케이스의 수 T, 각 테스트 케이스의 N(1 ≤ N ≤ 20)과 K(1 ≤ K ≤ 1000), 그리고 N개의 자연수 수열 A가 주어집니다. 수열의 원소인 N개의 자연수는 1 이상 100 이하입니다.

계획 수립

처음에는 조합을 전부 해보는 방식으로 접근했습니다.
import sys from itertools import combinations sys.stdin = open("input.txt", "r") T = int(input()) for test_case in range(1, T + 1): N, K = map(int, input().split()) A = list(map(int, input().split())) res = 0 for i in range(1, N): sums = [sum(comb) for comb in list(combinations(A, i))] res += sums.count(K) print("#%d %d" % (test_case, res))
Python
복사
예상대로 시간 초과가 발생해서, DP로 풀어보기로 했습니다.
한참 쓰다가 다시 생각해보니, 좀 더 단순하게 DP를 적용할 수 있었습니다.
import sys sys.stdin = open("input.txt", "r") T = int(input()) for test_case in range(1, T + 1): N, K = map(int, input().split()) A = list(map(int, input().split())) # dp[i] : i를 만들 수 있는 수열의 수 dp = [0] * (K+1) dp[0] = 1 for a in A: for i in range(K, a-1, -1): dp[i] += dp[i-a] print("#%d %d" % (test_case, dp[K]))
Python
복사

회고

오늘의 학습 포인트는 DP 문제에서 상태를 정의하는 방법과 점화식을 세우는 방법입니다. 처음에는 복잡하게 생각했지만, 문제를 단순화하니 쉽게 풀 수 있었습니다. 앞으로는 DP 문제를 풀 때 상태 정의와 점화식에 더 집중해야겠습니다.