일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- union find
- LCA
- dfs 백트래킹
- ccw
- Python
- 윤석열
- 재귀함수
- 내란죄
- 투 포인터
- dfs
- 오블완
- 백준
- 프림
- 왈왈왈
- 구조론
- 하버-보슈법
- 파비우스 전략
- 이분 탐색
- 분할정복
- 알고리즘
- 내란수괴
- 국민의 힘 뿌리
- 비상계엄
- 유니온 파인드
- 티스토리챌린지
- Prim
- 다익스트라
- BFS
- DP
- 내란수괴 윤석열
- Today
- Total
Toolofv 님의 블로그
[Python] 백준 2629 - 양팔저울 본문
문제
양팔 저울과 몇 개의 추가 주어졌을 때, 이를 이용하여 입력으로 주어진 구슬의 무게를 확인할 수 있는지를 결정하려고 한다.
무게가 각각 1g과 4g인 두 개의 추가 있을 경우, 주어진 구슬과 1g 추 하나를 양팔 저울의 양쪽에 각각 올려놓아 수평을 이루면 구슬의 무게는 1g이다. 또 다른 구슬이 4g인지를 확인하려면 1g 추 대신 4g 추를 올려놓으면 된다.
구슬이 3g인 경우 아래 <그림 1>과 같이 구슬과 추를 올려놓으면 양팔 저울이 수평을 이루게 된다. 따라서 각각 1g과 4g인 추가 하나씩 있을 경우 주어진 구슬이 3g인지도 확인해 볼 수 있다.
<그림 2>와 같은 방법을 사용하면 구슬이 5g인지도 확인할 수 있다. 구슬이 2g이면 주어진 추를 가지고는 확인할 수 없다.
추들의 무게와 확인할 구슬들의 무게가 입력되었을 때, 주어진 추만을 사용하여 구슬의 무게를 확인 할 수 있는지를 결정하는 프로그램을 작성하시오.
입력
첫째 줄에는 추의 개수가 자연수로 주어진다. 추의 개수는 30 이하이다. 둘째 줄에는 추의 무게들이 자연수로 가벼운 것부터 차례로 주어진다. 같은 무게의 추가 여러 개 있을 수도 있다. 추의 무게는 500g이하이며, 입력되는 무게들 사이에는 빈칸이 하나씩 있다. 세 번째 줄에는 무게를 확인하고자 하는 구슬들의 개수가 주어진다. 확인할 구슬의 개수는 7이하이다. 네 번째 줄에는 확인하고자 하는 구슬들의 무게가 자연수로 주어지며, 입력되는 무게들 사이에는 빈 칸이 하나씩 있다. 확인하고자 하는 구슬의 무게는 40,000보다 작거나 같은 자연수이다.
출력
주어진 각 구슬의 무게에 대하여 확인이 가능하면 Y, 아니면 N 을 차례로 출력한다. 출력은 한 개의 줄로 이루어지며, 각 구슬에 대한 답 사이에는 빈칸을 하나씩 둔다.
문제 해결 방법 - (서칭으로 참고후 해결)
1. 갖고 있는 추 리스트대로 dp를 구성한다. (행 인덱스는 '추의 갯수', 열 인덱스는 '구슬의 무게 - 추의 무게')이다. 재귀함수에 추의 갯수를 올려서 리턴하고 있고, 다음 추도 계속 올려야 할지 모르므로 1차원 DP는 짜기가 더 어렵다. 어떤 분기에서 DP에 이미 있는 무게면 다음 추를 올릴 수 없다.
2. l(왼쪽 저울), r(오른쪽 저울)을 만들고, 추의 리스트대로 idx를 증가시키며 각각 안 올릴 때, l에 올릴 때, r에 올릴 때의 분기를 가진 재귀함수를 만든다. abs(l-r)의 값은 결국 잴 수 있는 구슬의 무게다.
-> 결과적이긴 하지만, abs(l-r)의 값이 구슬의 무게일 때, 잴 수 있다는 거다.
1) 주어진 확인하고자 하는 구슬의 무게가 dp에 있으면 잴 수 있는 것이다.
3. 브루트포스 시 $O(3^{n})$의 시간복잡도를 가진다고 한다. dp로 먼저 계산된 값들은 제외시켜서 시간상 효율을 버는 것.
import sys
input = sys.stdin.readline
n = int(input())
d = list(map(int, input().split()))
m = int(input())
c = list(map(int, input().split()))
dp = [[0 for _ in range(15001)] for _ in range(n)]
ans = []
def sol(idx, l, r):
t = abs(l-r) # 잴 수 있는 구슬의 무게, 구슬의 처음무게는 이 함수에 올려놓지 않았다.
if t not in ans: # t의 값은 잴 수 있는 구슬의 무게다.
ans.append(t)
if idx == n:
return 0
if dp[idx][t] != 0: # 이미 dp에 기록된 잴 수 있는 구슬의 무게였다면 제외하는 것.
return
dp[idx][t] = 1
sol(idx+1, l, r)
sol(idx+1, l+d[idx], r)
sol(idx+1, l, r+d[idx])
sol(0, 0, 0)
for i in c:
if i in ans:
print('Y')
else:
print('N')
'Algorithm' 카테고리의 다른 글
[Python] 백준 - 1260 DFS와 BFS (2) | 2024.06.11 |
---|---|
[Python] 백준 - 3015 오아시스 재결합 (1) | 2024.06.07 |
[Python] 백준 11049 - 행렬 곱셈 순서 (0) | 2024.06.05 |
[Python] 백준 2293 - 동전 1 (1) | 2024.06.05 |
[Python] 백준 1520 - 내리막길 (0) | 2024.06.05 |