본문 바로가기

백준 PS일지/Greedy

[백준/Swift] 2217: 로프 | PS일지 | enumerated().map()에 관해..

문제

간단한 문제 요약

여러 개의 로프가 있다. 로프를 통해 물체를 들어올리는데  각각의 로프마다 중량이 있고, 병렬로 로프들을 연결할 수 있다. 그 대신 w/k 로 해서 로프들의 중량이 일치하도록 해야 병렬적으로 로프를 물체에 묶어 들어올릴 수 있다.

 

문제 풀이

 

정말 어려운 그리디..

 

어떻게 풀어야 할지 곰곰이 생각해봤습니다.

1 2 4 7 10 의 로프가 있을 때, "어떻게 최대한의 무게를 들 수 있을것인가?..." 이때 든 의문점은 중량 1의 로프와 중량 10의 로프를 같이 사용해서 물체를 올린다면 (10 + 1) / 2 =  5? 최대한으로 5씩 중량을 나눠서 들 수 있는데, 최대 중량 1짜리가 5를 들 수 있을까? 그럴 수 없을 것 같아서 내린 결론은 1로프와 10 로프를 같이 병렬적으로 사용할 땐 1 + 1 총 2 중량을 들 수 있다고 생각했습니다. 그리고 이 경우엔 병렬적으로 드는 경우보다 10 로프 한개만 사용할 때 중량 10까지 들 수 있습니다.

 

1 2 4 9999 이 경우 또한 혼자 사용하는 것이 베스트이기에,,

 

위의 경우처럼 무게가 클수록 무게가 낮은 것과 같이 병렬적으로 들게 되면 손해라고 생각했습니다. 그래서 나온 결론은.. 작은 것일 수록 병렬, 무거운 로프일 수록 혼자 사용.

 

1 2 4 7 10

1 1 1 1 1  (전체 - 0) * 1

2 2 2 2  (전체 - 1) * 2

4 4 4      (전체 - 2) * 4

7 7         (전체 -3) * 7

10          (전체 -4) * 10

!!

 


새롭게 알게 된 개념은.... 대박개념입니다. enumerated()를 사용한 후 map을 밥먹듯이 했는데, 이때마다 공식문서에서 나온 enumerated()는 튜플타입으로 (offset: element:) 를 반환합니다. map을 사용할 때 당연히 $0.offset, $0.element로만 받았었는데.. 잊고 있었던 경량 클로저의 특징을 라이노님이 알려주신 공식 문서 링크 덕에 확실하게 알게 되었습니다.. 대박 이걸 잊고 있었다니.

 

.map{ (first,last) in
    print("\(first) \(last)")
...
}

.map{ first, last in 
    print("\(first) \(last)")
}

.map{ 
    print("\($0) \($1)")
}

.map{ 
    print("\($0.offset) \($0.element)")
}

 

클로저의 특성상 이렇게 모두 사용이 가능하다는 사실을...

 

코드

print(
  (0..<Int(readLine()!)!)
  .map{_ in Int(readLine()!)!}
  .sorted(by: >)
  .enumerated()
  .map{($0+1)*$1}
  .max()!)