2096번 - 내려가기
2024-02-14
3분 분량
C++백준
문제 풀이 시간 : 1시간
문제 요약
- n줄에 0이상 9이하의 숫자가 세개씩 적혀있다.
- 첫줄에서 가장 마지막줄까지 이동하면서 세가지 숫자 중 하나를 고른다.
- 마지막 줄에서 얻을 수 있는 최대 점수, 최소 점수를 구해라
문제 풀이
이 문제는 dp로 풀 수 있겠다고 생각했다.
초기 코드
c++
#include <iostream>
#include <vector>
using namespace std;
int min_arr[100001][3], max_arr[10001][3], input[10001][3];
int dir[3][2] = {-1, 0, -1, -1, -1, 1};
int n;
bool check(int x, int y) {
if (x < 0 || x >= n || y < 0 || y >= 3)
return false;
return true;
}
void dp_min() { //최소 점수 구하기
int x = 1, y, tx, ty;
for (; x < n; x++) { //줄 번호
for (y = 0; y < 3; y++) { //줄 당 숫자
//현재 칸에 값을 초기화 해준다
min_arr[x][y] = input[x][y] + min_arr[x + dir[0][0]][y + dir[0][1]];
for (int i = 1; i < 3; i++) { //위의 다른 칸에서 내려왔을 때 경우 확인하기
tx = x + dir[i][0];
ty = y + dir[i][1];
if (!check(tx, ty))
continue;
if (min_arr[x][y] > input[x][y] + min_arr[tx][ty])
min_arr[x][y] = input[x][y] + min_arr[tx][ty];
}
}
}
}
void dp_max() { //최대 점수 구하기
int x = 1, y, tx, ty;
for (; x < n; x++) {
for (y = 0; y < 3; y++) {
max_arr[x][y] = input[x][y] + max_arr[x + dir[0][0]][y + dir[0][1]];
for (int i = 1; i < 3; i++) {
tx = x + dir[i][0];
ty = y + dir[i][1];
if (!check(tx, ty))
continue;
if (max_arr[x][y] < input[x][y] + max_arr[tx][ty]) {
max_arr[x][y] = input[x][y] + max_arr[tx][ty];
}
}
}
}
}
int main() {
cin >> n;
for (int i = 0; i < n; i++) {
cin >> input[i][0] >> input[i][1] >> input[i][2];
if (i == 0) { //첫번째줄 초기화 해주기
for (int j = 0; j < 3; j++) {
min_arr[0][j] = input[i][j];
max_arr[0][j] = input[i][j];
}
}
}
dp_min();
dp_max();
int min = min_arr[n - 1][0], max = max_arr[n - 1][0];
for (int i = 1; i < 3; i++) { //최대, 최소 점수 구하기
if (min > min_arr[n - 1][i])
min = min_arr[n - 1][i];
if (max < max_arr[n - 1][i])
max = max_arr[n - 1][i];
}
cout << max << " " << min;
}위 코드가 좀 더럽긴해도 맞다고 생각했는데
이상하게 3%에서 틀렸다고 뜬다.
이유는 모르겠다.
그래서 다른 사람의 풀이를 조금 참고했다.
최종 코드
c++
int main() {
cin >> n;
for (int i = 0; i < n; i++) {
cin >> input[0] >> input[1] >> input[2];
for (int j = 0; j < 3; j++) {
max_arr[i][j] = input[j];
min_arr[i][j] = input[j];
}
if (i == 0) {
continue;
} //무작정 큰값 대입해주기
max_arr[i][0] = max(max_arr[i - 1][0], max_arr[i - 1][1]) + input[0];
max_arr[i][1] = max(max_arr[i - 1][0], max(max_arr[i - 1][1], max_arr[i - 1][2])) + input[1];
max_arr[i][2] = max(max_arr[i - 1][1], max_arr[i - 1][2]) + input[2];
//무작정 작은값 대입해주기
min_arr[i][0] = min(min_arr[i - 1][0], min_arr[i - 1][1]) + input[0];
min_arr[i][1] = min(min_arr[i - 1][0], min(min_arr[i - 1][1], min_arr[i - 1][2])) + input[1];
min_arr[i][2] = min(min_arr[i - 1][1], min_arr[i - 1][2]) + input[2];
}
int min = min_arr[n - 1][0], max = max_arr[n - 1][0];
for (int i = 1; i < 3; i++) {
if (min > min_arr[n - 1][i])
min = min_arr[n - 1][i];
if (max < max_arr[n - 1][i])
max = max_arr[n - 1][i];
}
cout << max << " " << min;
}생각보다 너무 간단하고 무지성으로 풀 수 있었던 문제…
함께 읽으면 좋은 글
코딩 테스트2024-05-07
2186번 - 문자판
알파벳 문자가 한칸에 하나씩 적혀있는 NxM크기의 문자판이 있다. 임의의 칸에서 시작하여 상하좌우 K개의 칸까지 이동하며 문자를 모은다. 반드시 한 칸 이상 이동하며, 같은 자리에 머물 수 없다. 같은 칸을 여러 번 방문할 수 있다.
코딩 테스트2024-03-18
11657번 - 타임머신
N개의 도시가 있다. 한 도시에서 출발해 다른 도시에 도착하는 버스 M개가 있다. 각 버스는 A,B,C로 나타낸다. A-시작도시, B-도착도시, C-걸리는 시간 C는 양수가 아닐 수 있다.
코딩 테스트2024-02-20
16234번 - 인구 이동
NxN크기의 땅 한칸마다 나라가 존재한다. 국경선을 공유하는 두 나라의 인구 차이가 L명 이상, R명 이하라면 두 나라는 연합이 된다. 위의 조건에 해당하는 모든 나라가 연합이 되었다면 그 연합은 인구이동을 한다.
코딩 테스트2024-02-07
5525번 - IOIOI
n+1개의 I와 n개의 O로 이루어진 문자열이 있다. (IOIOI…) I,O로 이루언진 문자열 S가 주어졌을 때, S안에 위의 문자열이 몇번 포함되어 있는지 구해라 위 코드는 50점을 받았다.