728x90
반응형
https://www.acmicpc.net/problem/2342
1. Logic
DDR에서 이전에 갔던 곳을 똑같은 경우의 수로 갈 수 있기 때문에 메모이제이션을 활용하여 풀이했다. 규칙이 직관적으로 보여서 topdown으로 풀이하기 쉬웠다.
밟고 있던 위치를 다시 밟을경우 +1
처음 시작점인 0의 위치에서 움직일 경우 +2
인접한 위치로 움직일 경우 +3
반대편으로 움직일 경우 +4
처음에는 모든 경우의 수를 다 세줘서 보기 싫어서 최적화를 어떻게 해야할까 하다가, 그냥 규칙을 함수로 빼서 해결해줬다.
2. Code
최적화 전
#include<bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
int dp[100001][5][5];
vector<int> input;
int solve(int idx, int left, int right) {
if(idx == input.size()) return 0;
int &ret = dp[idx][left][right];
if(ret != -1) return ret;
ret = INF;
if(left == 0) ret = min(ret, solve(idx+1, input[idx], right)+2);
if(right == 0) ret = min(ret, solve(idx+1, left, input[idx])+2);
if(input[idx] == left) ret = min(ret, solve(idx+1, input[idx], right)+1);
if(input[idx] == right) ret = min(ret, solve(idx+1, left, input[idx])+1);
if(input[idx] % 2 == 1 && left % 2 == 0) ret = min(ret, solve(idx+1, input[idx], right)+3);
if(input[idx] % 2 == 1 && right % 2 == 0) ret = min(ret, solve(idx+1, left, input[idx])+3);
if(input[idx] % 2 == 0 && left % 2 == 1) ret = min(ret, solve(idx+1, input[idx], right)+3);
if(input[idx] % 2 == 0 && right % 2 == 1) ret = min(ret, solve(idx+1, left, input[idx])+3);
if(input[idx] % 2 == 1 && left % 2 == 1) ret = min(ret, solve(idx+1, input[idx], right)+4);
if(input[idx] % 2 == 1 && right % 2 == 1) ret = min(ret, solve(idx+1, left, input[idx])+4);
if(input[idx] % 2 == 0 && left % 2 == 0) ret = min(ret, solve(idx+1, input[idx], right)+4);
if(input[idx] % 2 == 0 && right % 2 == 0) ret = min(ret, solve(idx+1, left, input[idx])+4);
return ret;
}
int main() {
ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
memset(dp, -1, sizeof(dp));
while(true) {
int a;
cin >> a;
if(a == 0) break;
input.push_back(a);
}
cout << solve(0, 0, 0);
}
최적화 후
#include<bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
int dp[100001][5][5];
vector<int> input;
int move(int from, int to) {
if(from == 0) return 2;
if(from == to) return 1;
if(from%2 == to%2) return 4;
return 3;
}
int solve(int idx, int left, int right) {
if(idx == input.size()) return 0;
int &ret = dp[idx][left][right];
if(ret != -1) return ret;
ret = INF;
int leftMove = solve(idx+1, input[idx], right) + move(left, input[idx]);
int rightMove = solve(idx+1, left, input[idx]) + move(right, input[idx]);
ret = min(leftMove, rightMove);
return ret;
}
int main() {
ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
memset(dp, -1, sizeof(dp));
while(true) {
int a;
cin >> a;
if(a == 0) break;
input.push_back(a);
}
cout << solve(0, 0, 0);
}
알고리즘 Solve 후 제가 생각한 Logic을 기록하는 개인 공부 블로그입니다.
내용 중 최적화가 가능한 부분등은 언제든지 댓글로 틀린 부분 및 피드백 주시면 공부 및 반영하겠습니다🧐
728x90
반응형
'Algorithm > Programmers' 카테고리의 다른 글
[프로그래머스/Programmers] Level1 가장 많이 받은 선물 C++ :: Implementation (0) | 2024.02.02 |
---|---|
[프로그래머스/Programmers] Level 1 붕대감기 C++ :: Implementation (0) | 2023.12.13 |
[프로그래머스/Programmers] Level 3 숫자 게임 C++ :: Implementation (0) | 2023.10.03 |
[프로그래머스/Programmers] Level 2 마법의 엘리베이터 C++ :: Implementation (0) | 2023.09.27 |
[프로그래머스/Programmers] 점프와 순간 이동 Level.2 C++ (0) | 2023.07.28 |