https://www.acmicpc.net/problem/2342
2342번: Dance Dance Revolution
입력은 지시 사항으로 이루어진다. 각각의 지시 사항은 하나의 수열로 이루어진다. 각각의 수열은 1, 2, 3, 4의 숫자들로 이루어지고, 이 숫자들은 각각의 방향을 나타낸다. 그리고 0은 수열의 마
www.acmicpc.net
풀이
더보기




먼저 DP배열을 정의합니다.
DP[i번째발판을 누를차례][왼발위치][오른발위치] //i번째까지 도달하는데 사용한 최소힘 |
처음에는 상태가 이렇습니다.

0번차례(시작하지 않은상태)에 왼발 오른발 모두 0번 발판에 있습니다.
DP[0][0][0]으로 표현가능합니다.
예제 입력을 확인하면 1번 차례에 1번 발판을 밟으라고 나와있습니다.
1 2 2 4 0 |

두개의 상황이 나올 수 있겠네요.
왼발을 1번으로 옮겼을 경우 오른발을 1번으로 옮겼을경우
예제를 다시 확인해보면 2번 차례에 2번 발판을 밟으라고 나와있습니다.

다음과 같이 상황이 나올 수 있어요.
해당 그림을 통해서 점화식이 유추해보면 다음과 같습니다.
Arr : i번째에 밟아야되는 발판 DP : i번째까지 밟을때의 최소 힘 lc : 왼발로 다음발판을 밟았을때 드는힘(코드참고) l : 왼발의 위치 rc : 오른발로 다음발판을 밟았을때 드는힘(코드참고) r : 오른발의 위치 |
DP[i][l][r] =min(DP[i+1][Arr[i+1]][r] + lc, DP[i+1][l][Arr[i+1]] + rc); |
하지만 주의 해야할게 있어요!!

해당 사항을 고려해서 점화식을 수정하면..
Arr : i번째에 밟아야되는 발판 DP : i번째까지 밟을때의 최소 힘 D : 메모이제이션을 하기 위해 선언된 함수(코드참고) lc : 왼발로다음발판을 밟았을때 드는힘(코드참고) l : 왼발의 위치 rc : 오른발로 다음 발판을 밟았을때 드는힘(코드참고) r : 오른발의 위치 |
if(Arr[i + 1] != r) DP[i][l][r] = min(DP[i][l][r], D(i + 1, Arr[i + 1], r) + lc ); if(Arr[i + 1] != l) DP[i][l][r] = min(DP[i][l][r], D(i + 1, l, Arr[i + 1]) + rc ); |
코드
더보기
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
#define int long long
#define float double
const int INF = 0x3f3f3f3f3f3f3f3fLL;
int N = 1;
int Arr[100002];
int DP[100002][5][5]; //i번째까지 도달하는데 사용한 최소힘
int Cost[5][5] = {
{1,2,2,2,2},
{2,1,3,4,3},
{2,3,1,3,4},
{2,4,3,1,3},
{2,3,4,3,1}
};
int D(int i, int l, int r)
{
if (i >= N)
return 0;
if (DP[i][l][r] != INF)
return DP[i][l][r];
int rc = Cost[r][Arr[i + 1]] * (i + 1 < N);
int lc = Cost[l][Arr[i + 1]] * (i + 1 < N);
if (Arr[i + 1] != r)
DP[i][l][r] = min(DP[i][l][r], D(i + 1, Arr[i + 1], r) + lc);
if (Arr[i + 1] != l)
DP[i][l][r] = min(DP[i][l][r], D(i + 1, l, Arr[i + 1]) + rc);
return DP[i][l][r];
}
int32_t main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
memset(DP, INF, sizeof(DP));
while (true)
{
int a;
cin >> a;
if (a == 0)
break;
Arr[N++] = a;
}
cout << D(0, 0, 0) << endl;
}
-----------------------------------------------------------------------------------------------------------------------------------
질문은 언제나 환영합니다.
'알고리즘 > 문제풀이' 카테고리의 다른 글
백준 1062 가르침 (0) | 2021.07.08 |
---|---|
백준 21967 세워라 반석 위에 (0) | 2021.06.18 |
백준 11062 카드게임 (0) | 2021.06.03 |
백준 18133번 가톨릭대학교에 워터 슬라이드를?? (0) | 2021.06.03 |
백준 2579번 계단 오르기 (0) | 2021.06.02 |