GitHubSeob
C++ / 프로그래머스 / 카운트 다운 본문
문제
https://school.programmers.co.kr/learn/courses/30/lessons/131129
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
문제풀이
백준에서 DP로 풀었던 '1로 만들기'와 유사한 문제이다.
먼저 점수는 1~20, 1~20의 2의 배수, 1~20의 3의 배수, 50점 이렇게 있다.
셈을 하기 귀찮으므로 코드를 돌려 겹치는 부분을 제거했다.
여기서 중요한 점은 횟수는 최소로 하되, 횟수가 같으면 싱글(1~20), 불(50)을 최대한 많이 맞혀야 한다.
이중탐색을 통해 1점부터 시작하여 모든 과녁을 맞히는 경우를 탐색한다.
여기에 몇 가지 조건이 필요하다.
필수 조건은 과녁을 맞혔을 때 점수가 목표 점수이하여야 하다.
선택 조건은
1. 과녁을 맞혔을 때 점수가 처음 도달.
2. 점수를 이미 도달했다면 방금 던진 횟수를 포함하여 던진 다트 횟수가 적을 때
3. 점수도 같고 던진 횟수도 같지만, 싱글 or 불을 더 많이 맞혔을 때
이 세조건 중 하나라도 만족하면 다음으로 넘어간다.
현재 점수에 대한 정보를 갱신한다.
방금 던진 다트가 싱글이거나 불일 경우 횟수를 추가해 준다.
반복문이 종료될 때까지 위 작업을 반복하면 된다.
코드
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> solution(int target) {
int idx(0), idx2(0), next(0);
vector<vector<int>>DP(target + 1, vector<int>(2, 0));
vector<int>scores = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,26,27,28,30,32,33,34,36,38,39,40,42,45,48,50,51,54,57,60 };
for (idx = 0; idx <= target; ++idx) {
for (idx2 = 0; idx2 < scores.size(); ++idx2) {
next = idx + scores[idx2];
if (next <= target && (DP[next][0] == 0 || DP[idx][0] + 1 < DP[next][0] || (DP[next][0] == DP[idx][0] + 1 && DP[next][1] <= DP[idx][1]))) {
DP[next][0] = DP[idx][0] + 1;
DP[next][1] = DP[idx][1];
if ((1 <= scores[idx2] && scores[idx2] <= 20) || scores[idx2] == 50) {
DP[next][1]++;
}
}
}
}
return DP[target];
}
'Programmers > Level 3' 카테고리의 다른 글
C++ / 프로그래머스 / 입국심사 (0) | 2023.06.29 |
---|---|
C++ / 프로그래머스 / 선입 선출 스케줄링 (0) | 2023.06.29 |
C++ / 프로그래머스 / 억억단을 외우자 (0) | 2023.06.27 |
C++ / 프로그래머스 / 인사고과 (0) | 2023.06.27 |
C++ / 프로그래머스 / 거스름돈 (0) | 2023.06.27 |