본문 바로가기 메뉴 바로가기

박트리

프로필사진
  • 글쓰기
  • 관리
  • 태그
  • 방명록
  • RSS

박트리

검색하기 폼
  • 분류 전체보기 (49)
    • PS (19)
      • Codeforces (3)
      • BOJ (9)
      • Codeground (7)
    • Algorithm (4)
    • Data structure (0)
    • C++ (2)
    • etc. (24)
      • 대회 후기 (12)
      • 코딩테스트 후기 (6)
  • 방명록

티스토리 뷰

PS/Codeground

[코드그라운드 연습문제] 그릇 모으기

킹갓제네럴충무공 박트리 2017.04.12 23:35

그릇 모으기


문제


n개의 그릇 더미가 있다 각 그릇 더미는 최대 h개의 그릇이 쌓여있고 항상 큰 그릇 위에 작은 그릇을 놓을 때 주어진 연산들을 사용하여 한 개의 그릇 더미로 만드는 최소 연산 횟수를 구하는 문제이다.



문제 풀이


문제를 좀 더 단순화하여 약한 조건으로 생각해보자.

0번 그릇 더미를 새로 만들고 여기에 우리가 최후의 더미를 만든다는 조건과,

모든 그릇의 크기는 각각 다르다는 조건을 추가해보면 우리는 주어진 접시들을 소팅한 후 가장 큰 접시부터 0번 그릇 더미위에 올리면 된다.

따라서 현재 크기의 접시를 0번 그릇 더미 위에 올리는데 드는 연산 횟수는 다음과 같다.

먼저 현재 크기의 접시를 해당 그릇 더미 맨 아래 (그보다 큰 접시는 이미 0번 그릇 더미로 옮겨 졌기 때문에) 에서 분리하기 위해서는

현재 크기의 접시가 그릇 더미의 맨 꼭대기(현재 그릇 더미의 크기가 1) 이라면 0 아니라면 1의 연산으로 분리 가능하다. 

그리고 지금 0번 그릇 더미 맨 위에 올라와 있는 그릇의 더미 번호와 현재 접시의 더미 번호가 같다면 합치는데 비용이 -1이고 아니라면 1이다.

위와 같은 방식으로 구한 연산 횟수에 0번 그릇 더미(존재 하지 않는 그릇 더미)로 옮기는 연산 횟수인 1을 빼주면

우리가 구하고자 하는 최소 연산 횟수를 구할 수 있다. (시뮬레이션)


이제 문제는 같은 크기의 접시들이 여러개 존재 할 수 있다는 것인데, 

먼저 같은 그릇 더미에 같은 크기의 접시가 있다면 무조건(무적권!) 같이 움직이는게 이득이라는 점은 쉽게 생각할 수 있고,

다른 그릇 더미에서 같은 크기의 접시가 있을 때 어떤 순서로 0번 그릇 더미에 올려 놓을 것인가?

이 부분을 동적 계획법으로 구할 수 있다.

현재 크기의 접시를 모두 구해서 어떤 접시를 맨 아래로(현재까지 0번 그릇의 맨 위 접시와 관련이 됨) 보내고

어떤 접시를 맨 위로(다음에 들어오는 접시와 관련이 됨) 보낼지만 결정하면 가운데에 있는 접시들은 상관이 없다는 걸 알 수 있다.


따라서 

1. 현재 크기의 접시들중에 현재 0번 그릇 더미의 맨 위 접시의 더미 번호와 같은 접시가 있다면 

해당 그릇을 맨 아래로, 나머지 그릇들 중에 하나를 맨위로 보내고 연산수를 적절하게 구한다.

2. 존재하지 않는다면 맨 아래가 어떤 접시가 되도 상관이 없기 때문에, 하나의 그릇을 맨 위로 보내고 연산수를 적절하게 구하면 된다.


dp[i][j] = 0번 그릇 더미의 맨 위 그릇의 더미 번호가 j이고, 현재 i번째 크기의 그릇을 넣었을 때 최소 연산 횟수

로 정의 되고 현재 i 번째 그릇과 같은 크기를 가지는 그릇의 개수가 cnt개 라면

dp[ i+cnt ][ i 번째 그릇의 더미 번호 중 하나 ] = dp[i][j] + 연산수  로 구할 수 있다.

\(O(N^2H)\) 로 해결가능 하다.

 

소스 코드

코드 보기




 

 

저작자표시비영리변경금지
  • 카카오스토리
  • 트위터
  • 페이스북

'PS > Codeground' 카테고리의 다른 글

[코드그라운드 연습문제] 할인권  (0) 2017.04.13
[코드그라운드 연습문제] 부분배열  (0) 2017.04.13
[코드그라운드 연습문제] 그릇 모으기  (5) 2017.04.12
[코드그라운드 연습문제] 수강신청  (0) 2017.04.10
[코드그라운드 연습문제] 새로운 방  (0) 2017.04.10
[코드그라운드 연습문제] 김씨만 행복한 세상  (0) 2017.04.10
공유하기 링크
  • 페이스북
  • 카카오스토리
  • 트위터
TAG
DP
댓글
  • 프로필사진 박주현 좋은 아이디어를 많이 배웠습니다.!
    머리속에 떠오르는 이런 풀이를 코드로 깔끔하게 잘 구현하셨네요. 정말 많이 배워갑니다. 감사합니다~
    2017.04.13 11:39 신고
    댓글주소 수정/삭제 댓글쓰기
  • 프로필사진 킹갓제네럴충무공 박트리 Good 2017.04.13 19:24 신고
    댓글주소 수정/삭제
  • 프로필사진 조조 안녕하세요~이 코드에서 vector<pair<int, int> > dish; 이 부분이 이해가 안가는데 설명해 주실 수 있나요? 그리고 코드를 실행하려 했더니 flag와 dish가 식별자 정의가 되어 있지 않다고 하는데 어떻게 해야하나요? 2017.05.19 20:52 신고
    댓글주소 수정/삭제 댓글쓰기
  • 프로필사진 킹갓제네럴충무공 박트리 c++ 로 컴파일 하셨나요?
    stl에 대한 기본적인 이해가 있으신가요?
    2017.05.21 14:31 신고
    댓글주소 수정/삭제
  • 프로필사진 알린이 안녕하세요!!
    혹시 코드 중 25라인의 b[dish[i].second] != now부분이 잘 이해가 되지 않는데 왜 더미의 최대크기와 now를 비교하여 같지 않으면 연산수를 늘리는지 설명해주실 수 있을까요 ?
    2018.06.15 15:04 신고
    댓글주소 수정/삭제 댓글쓰기
댓글쓰기 폼
이전 1 ··· 25 26 27 28 29 30 31 32 33 ··· 49 다음
이전 다음
공지사항
  • 박트리의 블로그
최근에 올라온 글
  • 삼성전자 SW 역량테스트 B..
  • 알고리즘 공부, 어떻게 해..
  • 2018 SW교육 페스티벌 디지..
  • 2019 KAKAO BLIND RECRUITM..
최근에 달린 댓글
  • 정성글에 박수를 보냅니다!!..
  • 안녕하세요 글잘봤습니다 블록..
  • 좋은 글 감사합니다!
  • 공부할게 너무 많아서 엄두도..
Total
97,619
Today
224
Yesterday
369
TAG
  • 페르마 소정리
  • BIT
  • BFS
  • segment tree
  • sqrt decomposition
  • DFS
  • parametric search
  • DP
more
«   2019/02   »
일 월 화 수 목 금 토
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28    
글 보관함
  • 2018/10 (3)
  • 2018/09 (1)
  • 2018/08 (2)
  • 2017/11 (3)

Blog is powered by Tistory / Designed by Tistory
  • 페이스북 공유하기
  • 카카오톡 공유하기
  • 카카오스토리 공유하기
  • 트위터 공유하기