첫째 줄에는 추의 개수가 자연수로 주어진다. 추의 개수는 30 이하이다. 둘째 줄에는 추의 무게들이 자연수로 가벼운 것부터 차례로 주어진다. 같은 무게의 추가 여러 개 있을 수도 있다. 추의 무게는 500g이하이며, 입력되는 무게들 사이에는 빈칸이 하나씩 있다. 세 번째 줄에는 무게를 확인하고자 하는 구슬들의 개수가 주어진다. 확인할 구슬의 개수는 7이하이다. 네 번째 줄에는 확인하고자 하는 구슬들의 무게가 자연수로 주어지며, 입력되는 무게들 사이에는 빈 칸이 하나씩 있다. 확인하고자 하는 구슬의 무게는 40,000보다 작거나 같은 자연수이다.
출력
주어진 각 구슬의 무게에 대하여 확인이 가능하면 Y, 아니면 N 을 차례로 출력한다. 출력은 한 개의 줄로 이루어지며, 각 구슬에 대한 답 사이에는 빈칸을 하나씩 둔다.
입력 예시
2
1 4
2
3 2
출력 예시
Y N
풀이
DP 문제, 그 중에서도 배낭 문제의 확장판이라 볼 수 있는 문제이다.
현재 총 weight만큼 양팔저울에 올려져 있고 어떤 추 next_weight를 양팔저울에 넣을 때, 세 가지 가능성이 존재한다.
weight 쪽에 추를 올리기 : 이 때 총 무게는 weight + next_weight가 된다.
아무 것도 하지 않기 : 이 때 총 무게는 weight로 변동이 없다.
weight 반대쪽에 추를 올리기 : 이 때 총 무게는 weight - next_weight가 된다.
즉 세 가지 가능성이 발생한다. 또한 weight - next_weight 케이스의 경우 음수가 될 수 있다. 이 때는 양팔저울의 추를 서로 교환(swap)한다는 의미로, 절댓값을 취해 줄 수 있다. 따라서 i번째 추로 j만큼의 무게를 측정 가능한 경우(dp[i][j] = True), i+1번째 추를 이용하여 다음과 같은 점화식으로 표현 가능해진다.
총 무게는 40000g 까지 가능하며, 추가 30개까지 존재할 수 있으므로 30 * 3 * 40000안에 dp를 작성 가능하다.
init : 문제풀이에 필요한 정보를 입력받아 반환하는 함수이다.
make_weight_dp : 위에서 표현한 점화식에 따라 2차원 리스트 DP를 생성하여 반환하는 함수이다.
is_enable_measure_weight : 측정하고자 하는 무게 리스트 target_weight의 각 원소에 대해, DP의 그 무게에 해당하는 열을 검사하여 가능한지의 여부를 검사하는 함수이다. 검사 결과 리스트인 result 를 반환한다.
solve : 메인함수. init 함수로 받은 정보를 make_weight_dp 함수와 is_enable_measure 함수로 전달하고, 그 결과 리스트 result를 출력한다.
풀이 코드
def init() :
N = int(input())
weight_list = list(map(int, input().split()))
M = int(input())
target_weight = list(map(int, input().split()))
return N, M, weight_list, target_weight
def make_weight_dp(N, weight_list) :
dp = [[False]*40001 for _ in range(N)]
dp[0][0] = dp[0][weight_list[0]] = True
for i in range(N-1) :
next_weight = weight_list[i+1]
for j in range(40001) :
if dp[i][j] :
for k in [-1, 0, 1] :
dp[i+1][abs(j + k*next_weight)] = True
return dp
def is_enable_measure_weight(N, M, target_weight, dp) :
result = list()
for i in range(M) :
flg = False
for j in range(N) :
if dp[j][target_weight[i]] :
result.append('Y')
flg = True
break
if not flg :
result.append('N')
return result
def solve() :
N, M, weight_list, target_weight = init()
dp = make_weight_dp(N, weight_list)
result = is_enable_measure_weight(N, M, target_weight, dp)
print(*result)
solve()