사용자 도구

사이트 도구


ps:problems:boj:19133

Subset Sum

ps
링크acmicpc.net/…
출처BOJ
문제 번호19133
문제명Subset Sum
레벨다이아몬드 5
분류

fracturing search

시간복잡도O(nlogn + klogk)
인풋사이즈n<=200,000, k<=200,000
사용한 언어Python 3.11
제출기록66904KB / 732ms
최고기록732ms
해결날짜2024/10/16

풀이

  • 기본적으로는, 상태공간이 부분집합일 때에 [작성중] Fracturing Search를 사용하는 방법으로 풀 수 있다.
  • 여기서 신경써야 하는 부분은 음수값을 갖는 원소의 처리이다.
  • 단순한 아이디어로는, 음수 원소만 갖는 집합과, 양수 원소만 갖는 집합으로 분리해서 처리하는 방법이 있을수 있다.
    • 양수 집합과 음수 집합에서 각각 fracturing search를 적용해서 가장 작은 K개의 값들을 구한다. 길이 K의 배열 2개를 얻을 수 있다.
    • 이제 두 배열에서 원소를 한개씩 뽑아서 만든 페어들중 가장 값이 작은 K개를 다시 fracturing search를 적용해서 구한다
    • 세번의 fracturing search가 필요하고 각각은 O(klogk)의 시간이 걸리므로, 총 시간복잡도 역시 O(klogk)에 된다
    • 사실 이 방법을 생각한 뒤에, 더 좋은 방법을 떠올렸기에, 이 방법은 구현해보지 않았다. (실제로는 생각 못한 문제점이 있어서 안돌아갈수도 있다)
  • 좀더 좋은 아이디어는, 음수 원소들을 양수 원소로 변환하는 테크닉이다. 음수값을 갖는 원소들의 합 S를 먼저 구하고, 집합에서는 음수값을 갖는 원소들에는 절대값을 씌워준다. 이렇게 양수로 바뀐 원소가 포함된 부분집합은, 원래 집합에서 그 원소가 포함되지 않는 부분집합과 대응된다.
    • 예를 들어 {-1, -3, -10} 이라는 집합이 있을때
      • 원래 집합의 부분집합들은 {}, {-1}, {-3}, {-10}, {-1, -3}, {-1, -10}, {-3, -10}, {-1, -3, 10} 이다
      • 여기에 대응되는 집합들은 {1,3,10}, {3,10}, {1,10}, {1,3}, {10}, {3}, {1}, {} 이다
      • 원래 집합의 부분집합의 원소들의 합에서 14를 더하면, 대응되는 집합의 원소들의 합과 같아진다.
  • 이렇게 음수 원소들을 양수로 바꿔주게 되면 한번의 fracturing search 만으로 처리가 가능하다
  • 다만 이 경우에는, 공집합은 제외한다는 조건을 처리하는게 좀 귀찮아진다. K번째 이내에서 합이 0을 갖는 집합이 나왔다면, 이 중 한개는 공집합에서 나온 경우일 것이므로 한 개만 정답에서 제외해주는 식으로 처리하면 된다

코드

(다이아몬드 이상은 코드 생략)

토론

댓글을 입력하세요:
X F D U S
 
ps/problems/boj/19133.txt · 마지막으로 수정됨: 2024/10/16 08:38 저자 teferi