inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

2주만에 통과하는 알고리즘 코딩테스트 (2024년)

5강 최적화 19942번 질문드립니다.

해결된 질문

359

박성인

작성한 질문수 3

1

제가 코드를 짰는데 99퍼에서 오답처리가 났는데 어느부분을 놓쳤는지 모르겠어서 질문 드립니다.

코드 한 번 봐주실 수 있을까요..

def func(idx,p,f,s,v,sum1):
    global min_sum
    if sum1 > min_sum:
        return
    if idx == N:
        if p >= mp and f >= mf and s >= ms and v >= mv:
            if sum1 < min_sum:
                min_sum = sum1
                last1 = ''.join(map(str, visited))
                dict1[min_sum] = last1
                return
            elif sum1 == min_sum:
                return
        else:
            return
    else:
        visited[idx+1] = 1
        func(idx+1,p+info[idx][0],f+info[idx][1],s+info[idx][2],v+info[idx][3],sum1+info[idx][4])
        visited[idx+1] = 0
        func(idx+1,p,f,s,v,sum1)


N = int(input())
mp, mf, ms, mv = map(int, input().split())
info = [list(map(int, input().split())) for _ in range(N)]
min_sum = 999999999999999999
visited = [0] * (N+1)
dict1 = {}
func(0,0,0,0,0,0)

if min_sum == 999999999999999999:
    print(-1)
else:
    print(min_sum)
    for i in range(1,N+1):
        if dict1[min_sum][i] == '1':
            print(i, end=' ')

python 코딩-테스트 알고리즘

답변 2

1

박성인

답변 감사합니다!!

아직 이해 안되는 부분이 있어 댓글 답니다!

제가 강의를 보면서 이해한건

idx == N 까지 확인하는 경우면 결국 첫번째부터 마지막 요소까지 o,x로 그려나가면서

모든 부분집합을 훑는다고 이해했는데 이 부분에서 탐색하지 못한 반례가 있을 수 있는건가요?

 image

1

코딩 센세

아래 반례를 확인해보시면 됩니다!

 

제가 쓴 코드는, idx가 끝에 도달하지 않아도 정답 조건을 만족하면 정답을 업데이트 하고 종료되지만,

성인님이 쓴 코드는 반드시 마지막 idx에 도달하도록 조건이 걸려 있기 때문에,

영양소가 없는 재료 ( 좀 억지 반례이긴 하지만 ) 가 있다는 가정 하에 아래와 같이 다른 결과가 나오게 됩니다!

[반례]

3

0 0 0 1

0 0 0 1 1

0 0 0 0 0

0 0 0 0 0

 

[성인님이 쓴 코드 결과]

1

1 2 3

dict1 = {1: '0111'}

[제가 쓴 코드 결과]

1

1

dict1 = {1: '0100'}


이런 반례는 사실 저도, 처음부터 이런 반례가 있겠군! 하고 생각하고 푸는 건 아니고

조건문의 사용이나 가지치기의 위치, 등을 조금 반례가 생기지 않도록 문제를 계속 풀어보고 조정해 나가면서 자연스럽게 알게 되는 스킬이라서 정말로 좋은 질문이었습니다!

반례가 조금 억지네요.. 어이없다

 

1

박성인

와..

아 이해했습니다

늦은시간에 답변 주셔서 감사합니다

1

코딩 센세

조금 수정해봤습니다.

 

보내주신 코드와 결정적으로 다른점은

보내주신 코드

[ idx ==N일 때만, 영양소 조건을 확인해서 정답을 업데이트]

수정 한 코드

[ idx ==N이 아니더라도, 영양소 조건을 확인해서 정답을 업데이트]

 

해당 부분에 반례가 존재해서 99%에서 오류가 발생하는 것 같아요!

혹시라도 이해가 안되신다면 답글 남겨주세요!

 

def func(idx,p,f,s,v,sum1):
    global min_sum

    # 가지치기
    if sum1 > min_sum:
        return
    
    # 정답 업데이트    
    if p >= mp and f >= mf and s >= ms and v >= mv:
        if sum1 < min_sum:
            min_sum = sum1
            last1 = ''.join(map(str, visited))
            dict1[min_sum] = last1
            return
        
    # 인덱스 끝에 도달하면 탐색 종료    
    if idx == N:
        return
    
    # 탐색
    else:
        visited[idx+1] = 1
        func(idx+1,p+info[idx][0],f+info[idx][1],s+info[idx][2],v+info[idx][3],sum1+info[idx][4])
        visited[idx+1] = 0
        func(idx+1,p,f,s,v,sum1)


N = int(input())
mp, mf, ms, mv = map(int, input().split())
info = [list(map(int, input().split())) for _ in range(N)]
min_sum = 999999999999999999
visited = [0] * (N+1)
dict1 = {}
func(0,0,0,0,0,0)

if min_sum == 999999999999999999:
    print(-1)
else:
    print(min_sum)
    for i in range(1,N+1):
        if dict1[min_sum][i] == '1':
            print(i, end=' ')

dp[x]가 최대값이라고 확신할수 있는 이유

0

43

1

1090번 문제 질문

0

148

1

유니온파인드

0

111

1

투포인터 25:15 질문

1

127

1

#1090번 문제 반례가 궁금합니다.

0

145

1

예제코드 자바입니다

1

186

1

정수론 파트 #2247 문제에 대한 질문입니다!

0

101

0

코드 오류

0

185

1

2강 정수론 문제3 #1407 질문

0

126

0

이차원 배열 (int형)dp로 0 혹은 -1로 체크하는 방법 말고 boolean형 배열로 체크해서 바로 리턴해줄 수 없나요?

0

154

0

1717번 최적화

0

112

0

백준 22988 문제 질문

1

192

2

[Python] 백준 1090번 문제

1

223

3

강의자료에서

1

161

2

2503 문제 제한 조건 질문!

1

248

2

백준 22988 번 문제

1

191

1

추가 강의 순서

1

179

2

(*문제 풀이)1090 테스트케이스 1번 C++

1

219

2

7강 RGB 색칠하기 질문 있습니다.

1

160

2

정수론 약수 빠르게 구하기 질문

1

254

1

1090 문제의 2, 3번째 아이디어는 결국 같은거 아닌가요?

1

372

2

1090 문제 관련하여 맨해튼 거리 최솟값에 대해 질문 있습니다.

1

220

2

누적합 문제 3번 질문

1

213

2

기억 ( 누적합 ) 강의 11660 문제

1

161

2