※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 15822번 문제인 Ah-Choo!이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/15822
15822번: Ah-Choo!
입력의 첫 줄에는 파형의 길이를 나타내는 자연수 N이 주어진다. 두 번째 줄에는 첫 파형 X의 시간 별 높이를 나타내는 N개의 정수가 공백으로 구분되어 시간순으로 주어진다. 세 번째 줄에는 두
www.acmicpc.net
첫번째 파형의 [0,x] 구간과 두번째 파형의 [0,y] 구간 사이의 최소거리를 dp[x][y]라 하자. 이 값은 첫번째 파형의 시점 x와 두번째 파형의 시점 y 사이의 두 파형의 오차와 나머지 구간의 오차 중 최솟값, 즉 {첫번째 파형의 [0,x-1]구간과 두번째 파형의 [0,y-1] 구간 사이}, {첫번째 파형의 [0,x-1]구간과 두번째 파형의 [0,y-1] 구간 사이}, {첫번째 파형의 [0,x-1]구간과 두번째 파형의 [0,y-1] 구간 사이} 세 값중 가장 작은 값을 합한 것으로 계산할 수 있음을 관찰하자.
위의 관계를 이용해 점화식을 세워 메모이제이션을 통한 dp를 진행하는 프로그램을 작성해 문제를 해결하자. x=0 또는 y=0인 케이스에 대한 예외처리에 유의하자.
아래는 제출한 소스코드이다.
#include <iostream>
using namespace std;
typedef long long ll;
int N;
ll A[2000], B[2000];
ll dp[2000][2000];
bool visited[2000][2000];
ll func(int i, int j) {
if (visited[i][j]) return dp[i][j];
visited[i][j] = 1;
return dp[i][j] = min(func(i - 1, j - 1), min(func(i, j - 1), func(i - 1, j))) + (A[i] - B[j]) * (A[i] - B[j]);
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> N;
for (int i = 0; i < N; i++) cin >> A[i];
for (int i = 0; i < N; i++) cin >> B[i];
dp[0][0] = (A[0] - B[0]) * (A[0] - B[0]), visited[0][0] = 1;
for (int i = 1; i < N; i++) dp[i][0] = dp[i - 1][0] + (A[i] - B[0]) * (A[i] - B[0]), visited[i][0] = 1;
for (int i = 1; i < N; i++) dp[0][i] = dp[0][i - 1] + (A[0] - B[i]) * (A[0] - B[i]), visited[0][i] = 1;
cout << func(N - 1, N - 1);
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 1799 // C++] 비숍 (0) | 2023.08.23 |
---|---|
[BOJ 2546 // C++] 경제학과 정원영 (0) | 2023.08.22 |
[BOJ 6765 // C++] Icon Scaling (0) | 2023.08.22 |
[BOJ 3447 // C++] 버그왕 (0) | 2023.08.21 |
[BOJ 5370 // C++] Which Way (1) | 2023.08.21 |