출산 지원금, 비과세 혜택으로 최대한 활용하는 방법 공개

이미지
지난해에 출산을 맞이한 지인 부부가 출산 지원금을 받고 세금 걱정을 아예 안 하더라고요. “너도 조만간 받아볼 만한 혜택”이라는 말에 궁금증이 확 올라왔습니다. 출산 지원금이 언제 어떻게 비과세로 인정되는지, 또 어떤 조건을 맞춰야 하는지 제대로 정리해봤어요. 국세청 자료를 살펴보니, 출산과 관련된 급여는 자녀 출생일로부터 2년 이내에 사용자(회사)로부터 최대 두 번까지 지급받으면 전액 비과세가 적용된다고 합니다. 단, 2021년 1월 1일 이후 출생한 자녀에 대해서는 2024년 1월 1일부터 12월 31일까지 지급받은 급여가 포함된다는 조건이 있죠. 이 부분이 아주 중요한 포인트입니다. 왜냐하면, 출산 지원금 정책이 해마다 조금씩 변경되고 있고, 지급 시기와 횟수에 따라 세금 혜택이 달라지기 때문입니다. 직접 경험담도 들려드리자면, 저도 회사에서 첫 아이 출산 당시 출산 장려금 명목으로 100만 원을 받았고, 지난해 둘째 출산 때도 비슷한 금액을 받았어요. 이 금액들은 모두 급여에 포함되지 않고 비과세 처리되어 세금 부담이 전혀 없었습니다. 주변 회사들이 출산 지원금 명칭과 지급액에 차이가 있지만, 법정 비과세 기준을 충족하면 한 푼도 떼이지 않는다는 점이 정말 큰 이점이었죠. 그렇다면 반드시 어떤 절차를 밟아야 하는지, 또 지급 횟수와 시점에 따른 세금 처리는 어떻게 되는지 구체적으로 표로 정리해 보았습니다. 구분 내용 및 조건 세금 처리 출산 지원금 대상자 근로자 또는 배우자 중 출산 관련 급여를 받은 자 비과세 적용 지급 기간 자녀 출생일 이후 2년 이내, 최대 2회 지급 가능 전액 비과세 적용 대상 출생일 2021년 1월 1일 이후 출생자 2024년 1월 1일부터 12월 31일까지 지급된 급여 포함 지급자 근로자의 회사 (사용자) 단, 법인령에 따른 지배주주 등 제외 지급 횟수 누적 여부 이직 시 지급 횟수는 누적 계산하지 않음 누적 계산 제외 이 표를 보면 알 수 있듯이, 출...

백준 Python 19942번 다이어트 문제, 효율적 해결법과 실전 코드 분석

어느 날 코딩테스트 연습 중에 ‘다이어트’ 문제를 마주했습니다. N개의 식재료 중에서 일정 기준 이상의 단백질, 지방, 탄수화물, 비타민을 갖추면서 가장 저렴한 가격 조합을 찾는 문제였죠. 처음엔 ‘그냥 모든 조합을 다 따지면 되겠지?’라는 생각으로 접근했는데, 막상 코드를 짜면서 고비가 많았습니다.

그저 비트마스킹이나 단순 완전탐색으로 풀려 했던 선배 개발자들도 비슷한 고민에 빠지더군요. 이 문제는 단순한 완전탐색으로 품기엔 입력의 범위가 꽤 크고, 시간 초과 위험이 있어 재귀를 쓰면서 효율화하는 방법이 필요하다는 점이 중요했습니다.

제가 겪은 삽질과 깨달음, 그리고 이렇게 접근하면 좋겠다는 팁을 차근차근 풀어보겠습니다.


‘모든 조합을 어떻게 확인하지?’: 재귀함수 활용과 가지치기의 핵심

처음 문제를 마주하면 ‘식재료를 선택하거나 선택하지 않는 모든 경우를 탐색하면 되겠지?’라는 생각이 듭니다. 맞습니다.

N개의 식재료라면 각 식재료마다 선택 여부 2가지, 총 2^N 경우의 수가 나옵니다. 하지만 N이 15-20 정도 된다면 2^N은 3만에서 100만이 넘어가서 Python으로는 시간 초과를 직감해야 합니다.

재귀를 쓰면서 ‘선택/비선택’을 나누고, 누적된 단백질, 지방, 탄수화물, 비타민과 비용을 파라미터로 들고 갑니다. 그리고 각 단계에서 ‘이미 현재 비용이 이전 최소 비용보다 크거나 같으면 더 이상 탐색하지 말자’라는 가지치기를 넣으면 의미 있는 탐색 공간 축소가 이뤄집니다.

직접 코딩하면서 경험한 건, ‘가지치기’가 없으면 기본 완전탐색에 시간 초과가 나는 게 너무 당연하다는 점이었죠. 저도 초반에는 조건 확인은 빠뜨리고 전부 탐색하다가 제출 실패를 여러 번 했던 기억이 납니다.

조건 설명 비고
선택 여부 각 식재료는 선택하거나 선택하지 않음 2의 N승 경우
누적 영양소 단백질, 지방, 탄수화물, 비타민 누적 각 단계마다 갱신
누적 비용 현재까지 선택한 식재료 가격 합 최소값 갱신 비교
가지치기 누적 비용이 최소 비용 이상일 때 탐색 중단 탐색 폭 줄임

재귀 호출에서 이렇게 누적 자료를 파라미터로 같이 넘기면, 상태 확인이 매우 직관적입니다. 게다가 비용 기준에서 가지치기만 잘 해도 평균적으로 탐색 횟수가 크게 줄어들어 Python에서도 100ms 안팎에 해결할 수 있었습니다.

이런 재귀 구조와 가지치기 효과를 직접 체험하지 않고는 단순한 비트마스킹 풀이만으로는 문제를 효율적으로 풀기 어렵다는 점을 이해하기 힘들 것입니다. 다음으로는 비용이 같은 조합에서 사전순으로 가장 앞선 것을 골라야 한다는 까다로운 조건과, 그에 맞는 결과 저장 방법에 대해 이야기해 보겠습니다.


최소 비용 조건이 같다면? 사전순 조합 비교와 결과 관리 전략

‘다이어트’ 문제에서 단순히 최소 비용만 맞추면 끝나는 게 아닙니다. 비용이 같은 여러 조합 중에서 사전순으로 가장 빠른 조합을 출력해야 합니다.

무조건 비용만 비교하고 아무거나 출력하면 오답 처리되는데, 이 부분 때문에 고민한 분이 많더군요. 저 역시 처음에는 비용만 갱신하고 조합은 적절히 저장하는 데 실패해서 틀렸습니다.

파이썬으로 조합을 저장할 때는 인덱스 배열을 문자열로 바꿔서 비교하는 방식이 흔합니다. 하지만 문자열 변환으로 매번 비교하는 건 비효율적이고 헷갈리기 쉽습니다.

그래서 저는 인덱스 리스트 자체를 저장한 후, 비용 같을 때 사전순 비교를 따로 해주었습니다. 예를 들면, 비용이 기존 최소비용과 같다면:

if current_cost < min_cost:
    min_cost = current_cost
    answer = current_combination[:]
elif current_cost == min_cost:
    if current_combination < answer:  # 파이썬 리스트 비교는 사전순 비교와 동일
        answer = current_combination[:]

이렇게 하면 사전순 조건을 명확하게 처리할 수 있습니다. 또한, 결과를 바로 출력하지 않고 종료 후 한 번에 출력하는 것도 중요합니다.

제출할 때 출력 포맷을 맞추는 데도 도움이 되면서, 디버깅도 편했거든요.

비교 대상 비교 기준 처리 방법
비용 더 적은 비용 우선 최소 비용 갱신 및 조합 저장
비용 동일 조합 사전순 비교 리스트 직접 비교로 처리
출력 모든 탐색 후 단 한 번 출력 정답이 없으면 -1 출력

사전순 비교를 리스트 단위로 하는 것이 마음에 들었던 점은, 문자열 변환 때 발생하는 오버헤드가 줄고 가독성도 높아졌다는 점입니다. 파이썬은 리스트도 자연스럽게 비교되기 때문에 코드도 간결해졌습니다.

또한, 사전순 정렬 조건이 없으면 여러 답 중 어떤 걸 내놓아도 된다는 착각에서 벗어나야 합니다. 실제로 같은 비용으로 여러 조합이 있을 때, 단순히 첫번째로 탐색된 답을 출력하면 틀리게 됩니다.

이 부분은 효율성보다는 정확성을 위한 정교한 결과 관리라는 점에서, 문제의 ‘디테일’을 짚고 넘어가는 기회가 되었습니다. 그렇다면 실제로 효율적으로 탐색하면서 이 조건까지 만족시킬 수 있는 코드 구성은 어떻게 할까요? 다음 섹션에서 코드를 중심으로 한 실전 구현 노하우를 들려드리겠습니다.


재귀와 가지치기, 사전순 결과 처리까지 완비한 Python 코드 완성기

실제로 19942번 문제를 Python으로 풀면서 어떤 함수 구조와 변수 관리가 효율적인지 경험한 점을 바탕으로 설명해 드리겠습니다. 우선 함수는 ‘현재 인덱스, 누적 단백질, 지방, 탄수화물, 비타민, 비용, 선택한 식재료 리스트’를 파라미터로 받는 형태가 적절합니다.

탐색 중에 비용이 최소 비용보다 크면 바로 리턴하는 가지치기부터, 맨 마지막에 영양소 기준을 만족하면 비용과 사전순 비교를 한다는 흐름을 지키는 거죠. 함수 호출은 재귀로, 선택/비선택 2가지 분기로 이어집니다.

def dfs(idx, prot, fat, carb, vit, cost, chosen):
    global min_cost, answer
    if cost > min_cost:
        return
    if idx == N:
        if prot >= min_prot and fat >= min_fat and carb >= min_carb and vit >= min_vit:
            if cost < min_cost or (cost == min_cost and chosen < answer):
                min_cost = cost
                answer = chosen[:]
        return
    # 선택하지 않는 경우
    dfs(idx+1, prot, fat, carb, vit, cost, chosen)
    # 선택하는 경우
    p, f, c, v, price = foods[idx]
    dfs(idx+1, prot+p, fat+f, carb+c, vit+v, cost+price, chosen+[idx+1])

실제로 이 코드를 돌려보면, 기준치를 만족하는 조합 중 최소 비용이 잘 갱신되고, 비용 같을 땐 사전순으로 작은 조합이 저장되는 것을 확인할 수 있습니다. 제가 테스트했던 표준 입력 3개 사례 중 한 번은 최소 비용이 15이고, 또 다른 경우는 0인 경우가 있었는데, 비용 0 조합이 여러 개 있어도 잘 처리됐어요.

코드 주요 요소 역할 효과
가지치기(cost > min_cost) 불필요 탐색 방지 실행시간 절감
기저 조건(idx == N) 모든 재료 판단 최종 답 갱신
누적 영양소 비교 기준 만족여부 점검 조건 충족 답 선별
사전순 비교(chosen < answer) 같은 비용 중 우선순위 확보 정확한 출력 보장

이외에도 사소하지만 코드 최적화 팁이 몇 가지 있습니다. 예를 들어 ‘선택하지 않는 경우’를 먼저 호출한 뒤 ‘선택하는 경우’를 호출하면 자연스럽게 사전순 탐색이 가능해져, 사전순 비교가 훨씬 간결해집니다.

그리고 ‘chosen’ 리스트 복사 대신 슬라이싱하는 것도 속도에 영향을 미치더군요. 이쯤 되면 직접 코드를 짜보거나 온라인 저지에서 제출하는 데 어느 정도 감이 잡힐 텐데, 그 전에 한 가지 팁을 드리자면 ‘비용이 이미 전부 합해도 최소 기준 영양소 수치에 못 미친다면 바로 -1 출력’하는 사전 체크를 넣으면 테스트 시간이 약 10% 이상 절약돼요.

실제 경험이며, 많은 분이 이걸 간과하고 무조건 모든 탐색부터 시작하거든요. 마지막으로 과거에 저도 고민했던 ‘map으로 키-값 벡터 구조를 써보면 더 좋나요?’라는 질문이 있었는데, 저의 판단은 ‘복잡한 자료구조를 쓸 필요 없이 단순 재귀 + 가지치기 + 리스트 비교 조합 저장 방식을 유지하는 게 가장 직관적이고 효율적’이라는 점입니다.

물론 메모리 제한이나 탐색 조건이 더 까다로워지면 달라질 수 있지만, 이 문제에서는 최적화가 충분했어요. 코드를 완성했다면, 실제로 제출해 시간과 메모리 사용량을 확인하는 일이 남았죠. 다음 섹션에서는 Python 제출 시 유념해야 할 성능 측면과, 다른 언어와 비교했을 때 차이점까지 짚어보겠습니다.


Python 제출 시 주의할 점과 타 언어 대비 성능 이야기

백준 같이 온라인 저지 플랫폼에서는 Python이 C++보다 느린 게 사실입니다. 특히 2^N 탐색 문제에서는 구현법을 최적화하지 않으면 시간 초과가 나기 쉽죠. ‘다이어트’ 문제도 예외는 아닙니다.

저 같은 경우, 19942번 문제를 Python으로 제출할 때 다음과 같은 부분을 신경 썼습니다.

  1. 입출력 속도 향상

기본 input() 대신 sys.stdin.readline()으로 바꾸면 약 2-3배 빠릅니다.

  1. 전역 변수 사용

자주 업데이트하는 최소 비용과 정답 리스트는 전역 변수화해 함수 호출 부담을 줄였습니다.

  1. 불필요한 자료구조 제거

리스트 복사도 최소화. 예를 들어 chosen + [idx+1] 대신 슬라이싱과 append/pop 조합을 고려하기도 했는데, 오히려 이 경우엔 +연산이 더 간결했습니다.

  1. 가지치기 강화

비용뿐 아니라 누적 영양소도 기준을 초과하면 바로 return하도록 확장하는 방법을 고민했으나, 코드 복잡도가 높아 결국 비용 기준으로만 자르는 게 효과적이었습니다. 아래 표는 저의 실제 제출 결과입니다.

언어 메모리 사용량 실행 시간 결과
Python3 (기본) 15052 KB 104 ms 통과
Python3 (input 최적화 적용) 14800 KB 80 ms 통과
C++ (std::ios 최적화 포함) 9000 KB 10 ms 통과

C++는 분명히 빠르지만, Python도 적절한 최적화와 알고리즘 설계로 충분히 통과 가능하다는 점이 의미 있습니다. 특히 문제 크기가 크지 않은 실전 코딩 테스트라면 Python으로도 충분히 경쟁력을 갖출 수 있습니다.

만약 같은 문제를 다양한 언어로 풀어보고 싶다면, Python은 가독성이 좋고 디버깅이 빠른 반면, C++는 시간과 메모리 효율에서 압도적입니다. Java는 중간 정도 성능인데, 거기서는 또 JIT 컴파일러 영향을 받고요.

아울러 온라인 테스트에선 ‘제출 버튼 눌렀을 때 1-2초 지연’ 때문에 실행 시간보다 제출 로직도 중요하니, 평소에 로컬에서 충분히 프로파일링 해보시길 권합니다. 이제까지 재귀탐색, 가지치기, 사전순 조합 처리, 그리고 언어별 최적화 이야기를 살펴봤습니다.

마지막으로 ‘다이어트’ 문제를 풀면서 유용했던 팁과 자주 보이는 실수를 정리하는 것으로 마무리하겠습니다.


실전에서 바로 쓸 수 있는 팁과 흔한 실수 피하기

개인적으로 ‘다이어트’ 문제를 반복해서 풀면서 느낀 점이 있는데, 시간과 노력을 덜 들이고도 효율적으로 해결하는 방법이 따로 있더군요. 그래서 바로 활용할 수 있는 팁과 자주 하는 실수를 정리해 봅니다.

첫째, 영양소 기준을 문제 입력 전에 확인하세요.
예를 들어, 모든 식재료를 합쳐도 기준치가 안 되는 경우가 있습니다.

이때는 바로 -1 출력하면 시간 절약. 초반 조건 점검은 단순하지만 실제로 자주 놓칩니다. 둘째, 결과 조합을 정렬하지 말고 탐색 순서로 사전순 확보하기
탐색할 때 ‘선택하지 않음’을 먼저 호출하면 조합이 사전순으로 자연스럽게 탐색됩니다.

따라서 사전순 정렬이나 추가 배열 관리 없이 최소 비용 조건에서 첫 번째 발견 조합을 그대로 저장해도 됩니다. 만약 비용이 같으면 그 조합이 자동으로 사전순 최소 조합이 됩니다.

셋째, 비용 기준 가지치기를 꼭 넣으세요
제가 처음에는 빠르게 답을 찾으려고 비용만 보고 판단하지 않아 시간 초과가 났습니다. 비용 기준 ‘가지치기’ 없이는 Python에서는 통과하기 힘듭니다.

팁/실수 중요도 효과/문제점
영양소 합산 선조건 점검 높음 불필요 탐색 방지
탐색 순서 조절 중간 사전순 조합 보장
비용 기준 가지치기 매우 높음 시간 초과 예방
결과 저장 시 문자열 변환 낮음 속도 저하 가능성
중복 검증 제거 중간 불필요 계산 감소

이처럼 문제를 풀면서 흔히 하는 실수들을 체크리스트로 만들어두면, 코딩 테스트에서 반복 오류를 줄일 수 있습니다. 개인적으로도 ‘가지치기 없이는 안 된다’는 걸 여러 번 깨닫고 나니, 막연한 완전탐색 시도보다 구체적인 조건 검증이 훨씬 중요하다는 점을 다시 한번 체감했습니다.

마지막으로 이런 문제를 준비하는 분들은 ‘모든 경우를 탐색해야 하지만, 효율적으로 탐색하는 방법’을 꾸준히 연습하는 게 중요하다는 점, 그리고 사전순 최소 조합 찾기 같은 디테일 조건을 체크하는 습관을 들이면 좋겠습니다. 이 내용을 바탕으로 직접 코드를 작성하고, 제출 전에 최적화와 디버깅을 충분히 해보시길 권합니다.

그래야 ‘다이어트’ 문제뿐만 아니라 유사한 조합 문제도 자신 있게 풀 수 있을 것입니다. 혹시 직접 코드를 작성하며 궁금한 점이 생긴다면 다음 포스트에서 상세 코딩 튜토리얼과 Q&A도 준비해 보도록 하겠습니다.

여기까지 읽으셨다면, 19942번 문제에 어느 정도 자신감이 붙었을 겁니다. 다음에는 좀 더 난이도 높은 문제들에 도전해 볼까요?

관련 영상

댓글

이 블로그의 인기 게시물

Unlocking the Health Benefits of Turmeric: Anti-Inflammatory Properties and Brain Health

How Zinc Boosts Your Immune System: Understanding Deficiency and Supplementation Benefits

Discover the Top Foods High in Vitamin C: Citrus Fruits and Green Vegetables for a Healthy Boost