Traveling Salesperson Probelm
2회차 문제 풀이 복기
2번째 푸는 것인데도 문제가 낯설게 느껴졌지만! 순열을 이용하여 푼다는 것을 깨닫고 차근히 풀어나가봤다!
알고리즘 생각
첫번째 순열 : 오름차순 마지막 순열 : 내림차순
1234에서 사전증가순 다음 순열은 1243이 된다. 이렇게 직관적으로 찾은 이유는 끝에서부터 a[i-1]<a[i]인 i를 찾아야한다!
틀린 부분(틀린 이유)
배열범위초과 a[i-1]과 a[i]를 비교하는 것이기 때문에 i는 0보다 크다고 해주어야 배열 범위를 벗어나지 않는데 i>=0으로 해서 i가 0이 될 때까지 진행해버려 a[i-1]가 배열범위를 벗어나 에러가 났다.
2. 스코프 문제 do-while문은 next_permutation(d)의 다음 순열이 true인 동안 계속해서 실행되며 다음 순열을 생성한다. do-while문을 반복하면서 생성되는 각 순열에 대해 순회 비용과, 유효성 검사를 초기화해주어야하는데 sum과 ok를 do-while문 밖에 두어 초기화를 해주지 않아서 오답이 나왔다. 원래 최소비용 정답은 35인데 오답으로 39가 나왔다. 그 이유는 sum을 초기화하지 않고 계속 더해갔기 때문이다. 첫번째 순회 비용은 39이고 그 다음 순열의 순회 비용이 35라서 정답은 35가 나와야하지 39+35=74, 74+x+x2....가 sum은 계속적으로 더해진다. 첫 번째 순회 비용이 최솟값이 아님에도 불구하고 sum은 계속 더해지기 때문에 첫번째 순회 비용이 정답으로 나왔다.
3. while 조건문 설정 i와 j가 같으면 재정렬할 필요 없지만 그렇지 않은 경 a[i-1]과 a[j]를 바꾼 후 i보다 작은 a[i-1]이 i의 뒤에 왔으니 i 뒤의 숫자들을 오름차순으로 재정렬해주어야한다. j는 끝에서부터 시작하고, a[i]와 a[j]를 바꾸어준다. i는 1씩 증가, j는 1씩 감소시킨다. 이 연산을 언제까지 반복해야하는가? 1)i가 j와 같아질 때까지(i와 j가 다르면 계속 반복) : while(i!=j) => i++,j-- 결국 배열범위 초과한다! 2)i++<n && j-->=0 : i뒤의 숫자들만 swap해서 재정렬하면되는데 전체 숫자들을 다 바꿔버리게 된다! 그렇다면 반복조건은 무엇인가? 생각을 해보면 i<j인 상황에서 a[i]<=>a[j]하고 i++,j-- 하다가 j < i가 되면 정렬이 완료되어 그만하면 된다! 그렇다면 i<j인 동안에만 반복해주면되기 때문에 while 반복 조건은 while(i<j) 가 된다!
Last updated