일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 29 | 30 | 31 |
- 백준
- BOJ
- graph
- CS Academy
- BFSDFS
- Eulerian path
- DynamicProgramming
- BST
- dynamic programming
- backtracking
- bitmask
- mathematics
- flows
- hashing
- scc
- Eulerian circuit
- GCD
- Euler circuit
- Greedy
- Algospot
- graph modeling
- disjoint-set
- POJ
- implementation
- Cycle detecting
- Segment Tree
- Shortest path
- Dag
- Euler path
- Sieve_of_Eratosthenes
- Today
- Total
그냥 하는 노트와 메모장
BOJ 10564 - 팔굽혀펴기 본문
* BOJ 10564 - 팔굽혀펴기
[분류 - 다이나믹 프로그래밍]
처음엔 생각나는대로 풀었는데 시간과 메모리가 마음에 안들어서 계속 생각하다 문득 떠오른 풀이를 공유하고자 합니다.
[첫 풀이]
2차원 배열에서 dp[누적 회수][팀이 득점한 총 점수]로 설정해서 O(M N^2) 시간 복잡도를 갖는 풀이를 써봤습니다. 직관적이고 이해하기 쉬워서 작성은 금방했습니다만, 여러 테스트 케이스를 고려하면 "누적 회수"가 "팀이 득점한 총 점수"에 의존적으로 결정되기 때문에 N^2을 모두 채우지 않을거라는 기도 메타에 약 800ms으로 풀이가 맞았습니다.
[보다 확실하고 효율적인 풀이]
'이전 경기 결과에서 다음 경기에 점수 얼마를 얻었다'가 아니라 반대로 생각해봅시다. '첫 경기를 추가해보자'라고.
그러면 문제는 갑자기 단순해집니다. 가령 현재 세 번째 경기에서 팔굽혀펴기 회수가 10이고, 첫 경기를 7점으로 추가해봅시다. 그러면 총 네 번 경기해서 팔굽혀펴기 회수가 10 + 7 * 4 = 38로 바로 계산이 됩니다.
[경기 회수?] 네 이것이 바로 핵심입니다. 경기 회수를 고정해봅시다. 1회, 2회 그리고 3회 계속해서 n회까지 거듭하며 얻을 수 있는 점수를 다이나믹하게 계산해보는 겁니다. 예를 들어 5번째 경기 결과는 4번째 경기 결과에서 첫 경기를 추가해주는 방식입니다. 마찬가지로 11번째 경기 결과를 10번째 경기 결과에서 첫 경기를 추가해주는 겁니다. (이 아이디어는 https://www.acmicpc.net/problem/2419에서 가져왔습니다. 풀이 링크는 https://coloredrabbit.tistory.com/92)
[경기 회수의 최대값 L] 이건 간단하게 구할 수 있습니다. 경기 회수를 많이해서 N이 될 수 있으려면 S중 가장 최소 점수로 점수를 계속 득점해나갔다고 생각하면 됩니다. 최악의 경우에 이 값이 1일텐데 계속 1을 누계해서 N이 되려면 L(L+1)/2 = N의 방정식이 성립됩니다. 따라서 L의 최대값은 99입니다(100이면 100 * 101/2 = 5050이기에 N최대 초과).
[그래도 O(L M N^2)] 하나 더 생각해볼 것이 있어요. 바로 경기 회수에 대한 최소값 설정입니다. 만약 경기를 5번 했다고 가정해봅시다. 여기서 총 팔굽혀펴기 회수가 1이 될 수 있을까요? 절대 불가능합니다. S중 최소값을 minS라고 하면 적어도 minS * 5 * 6 / 2번을 해야하기 때문이죠. 따라서 경기 회수를 진행하면 진행할 수록 팔굽혀퍼기 회수의 최소값은 점점 커집니다. 이 최소값을 유지하면 수많은 가지를 쳐낼 수 있어요.
[참고 - 슬라이딩 윈도우] 경기 회수에 대해서 i번째 경기 회수를 한 경우는 i-1번째 경기 회수를 부분 문제로 두고 있습니다. 이 부분은 슬라이딩 윈도우로 메모리까지 아낄 수 있답니다.
'Solved problems' 카테고리의 다른 글
BOJ 5580 빙고 게임 (0) | 2020.05.20 |
---|---|
BOJ 3026 V (0) | 2020.05.18 |
BOJ 14559 - Protocol (2) | 2020.02.26 |
BOJ 13011 - 사탕의 밀도 (0) | 2020.02.26 |
BOJ 13010 - h(n) (0) | 2020.02.25 |