[Python-CodingTest] 6-4. 합이 같은 부분집합 (DFS: 깊이우선탐색)
합이 같은 부분집합
문제 정리
입력
6
1 3 5 6 7 10
처리 과정
- 원소들을 리스트 형태로 입력받기
- 리스트의 합(
=total
) 계산 - DFS의 파라미터로 인덱스(
=i
)와 누적합(=sum
) 전달 i
가n
과 같지 않을 때, DFS에 다음 인덱스(=i+1
)와 누적합을 전달- 이때 누적합은 원소로 사용될 때는 해당
lst
값을 누적하고, 사용되지 않을 때는 그대로 전달 n-1
까지 계산한 뒤,i
가n
이 되면, 누적합(=sum
)과total-sum
이 같은지 확인
출력
YES
내 답
import sys
sys.stdin = open("./input/in4.txt", "rt")
def DFS(i): # i는 인덱스 번호
sum=0
if i==n: # 맨 마지막 요소 다음
for k in range(n):
if ch[k]==1:
sum+=numbers[k][1]
if sum==total-sum:
print('YES') # YES가 4번 출력..🤔
else:
ch[i]=1 # 부분집합으로 사용
DFS(i+1)
ch[i]=0 # 부분집합으로 사용X
DFS(i+1)
if __name__=="__main__":
n=int(input())
# 튜플 형태로 받기
numbers=[(idx,val) for idx,val in enumerate(list(map(int,input().split())))]
ch=[0]*(n+1)
total=0
for i in range(n):
total+=numbers[i][1]
DFS(0) # 파라미터는 인덱스 번호
YES
가 4번 출력됨..
풀이 - 1
import sys
sys.stdin = open("./input/in4.txt", "rt")
def DFS(i,sum): # i는 인덱스 번호, sum은 원소의 누적 합
if i==n:
if sum==total-sum:
print('YES')
sys.exit(0) # 프로그램 종료
else:
DFS(i+1,sum+lst[i]) # lst[i]를 원소로 사용 -> sum에 누적
DFS(i+1,sum) # lst[i]를 원소로 사용X -> sum은 그대로
if __name__=="__main__":
n=int(input())
lst=list(map(int,input().split()))
total=sum(lst) # lst의 합 구하기
DFS(0,0)
print('NO') # sys.exit(0)으로 종료되지 않았다면 NO
풀이 - 2: 시간 복잡도를 줄여보자
DFS()
안에서 sum==total-sum
이 성립하려면, sum
이 total
의 절반을 넘기면 안됨!
부분집합의 원소를 sum
에 누적하다가 total
의 절반을 넘으면 더이상 진행하지 않고 NO
import sys
sys.stdin = open("./input/in4.txt", "rt")
def DFS(i,sum):
if sum>total//2: # 시간복잡도를 줄이기 위한 조건 추가
return
if i==n:
if sum==total-sum:
print('YES')
sys.exit(0)
else:
DFS(i+1,sum+lst[i])
DFS(i+1,sum)
if __name__=="__main__":
n=int(input())
lst=list(map(int,input().split()))
total=sum(lst)
DFS(0,0)
print('NO')
정리
- 프로그램을 종료할 때는
sys.exit(0)
💛 개인 공부 기록용 블로그입니다. 👻