문제 링크: www.acmicpc.net/problem/17498
17498번: 폴짝 게임
첫 번째 줄에 행의 개수 N과 열의 개수 M (2 ≤ N×M ≤ 200,000, 2 ≤ N) 그리고 최대 점프 거리 정수 D (1 ≤ D ≤ 10) 가 주어집니다. i+1 번째 줄에는 i (1 ≤ i ≤ N) 번째 행에 있는 쓰여있는 정수 ai,1, ai,2,
www.acmicpc.net
카테고리는 다이나믹 프로그래밍입니다.
아직 제가 다이나믹 프로그래밍에 대한 이해가 부족한 탓인지,
일단 제 생각대로 구현을 성공적으로 했는데,
시간 초과 오류에 걸려 버리네요.
검색해보니 다이나믹 프로그래밍 중,
계산한 값을 배열에 미리 담아 두는 '메모이제이션' 기법이 있다고 합니다.
내일 관련 내용을 공부한 후 처음부터 다시 도전해봐야겠습니다.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <vector> | |
#include <cmath> | |
//#include <time.h> | |
#define MIN_VALUE -1e12 | |
using namespace std; | |
int N, M, D; | |
vector <vector <int > > v; | |
vector <int> v2; | |
long long score = 0; | |
long long currentMax = MIN_VALUE; //현재의 최대값; 새 좌표 시작시마다 0으로 초기화됨 | |
int currentN = 0; | |
int currentM = 0; //현재의 최댓값이 위치한 좌표 | |
int locationN = 0; | |
int locationM = 0; //현재 위치한 좌표 | |
//시작행, 시작열, 도착행, 도착열 | |
bool isReachable(int startN, int startM, int endN, int endM) { | |
if (startN > endN) | |
return false; | |
if (abs(endN-startN) + abs(endM-startM) <= D) | |
return true; | |
else | |
return false; | |
} | |
void search(int startN, int startM, int goalN, int goalM) { | |
if (isReachable(startN, startM, goalN, goalM) == false) | |
return; | |
int temp = v[startN][startM] * v[goalN][goalM]; | |
if (temp > currentMax) { | |
currentMax = temp; | |
currentN = goalN; | |
currentM = goalM; | |
} | |
} | |
void reset() { | |
score += currentMax; | |
currentMax = 0; | |
locationN = currentN; | |
locationM = currentM; | |
currentN = 0; | |
currentM = 0; | |
} | |
int main() { | |
/*clock_t start,end; | |
start = clock(); */ | |
ios_base::sync_with_stdio(false); | |
cin >> N >> M >> D; | |
for (int i = 0; i < N; i++) { | |
v.push_back(v2); | |
for (int j = 0; j < M; j++) { | |
int input; | |
cin >> input; | |
v[i].push_back(input); | |
} | |
} | |
for (int i = 0; i < M; i++) { | |
for (int j = 1; j < N; j++) { | |
for (int k = 0; k < M; k++) { | |
search(locationN,i,j,k); | |
} | |
} | |
} | |
reset(); | |
while (locationN != N-1) { | |
for (int i = locationN+1; i < N; i++) { //탐색 대상이 되는 N | |
for (int j = 0; j < M; j++) { //탐색 대상이 되는 M | |
search(locationN,locationM,i,j); | |
} | |
} | |
reset(); | |
} | |
cout << score; | |
/* | |
end = clock(); | |
double result = (double)(end-start); | |
cout << '\n' << result << endl; | |
*/ | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <vector> | |
#include <cmath> | |
//#include <time.h> | |
#define MIN_VALUE -1e12 | |
using namespace std; | |
int N, M, D; | |
vector <vector <int > > v; | |
vector <int> v2; | |
long long score = 0; | |
long long currentMax = MIN_VALUE; //현재의 최대값; 새 좌표 시작시마다 0으로 초기화됨 | |
int currentN = 0; | |
int currentM = 0; //현재의 최댓값이 위치한 좌표 | |
int locationN = 0; | |
int locationM = 0; //현재 위치한 좌표 | |
//시작행, 시작열, 도착행, 도착열 | |
bool isReachable(int startN, int startM, int endN, int endM) { | |
if (startN > endN) | |
return false; | |
if (abs(endN-startN) + abs(endM-startM) <= D) | |
return true; | |
else | |
return false; | |
} | |
void search(int startN, int startM, int goalN, int goalM) { | |
if (isReachable(startN, startM, goalN, goalM) == false) | |
return; | |
int temp = v[startN][startM] * v[goalN][goalM]; | |
if (temp > currentMax) { | |
currentMax = temp; | |
currentN = goalN; | |
currentM = goalM; | |
} | |
} | |
void reset() { | |
score += currentMax; | |
currentMax = 0; | |
locationN = currentN; | |
locationM = currentM; | |
currentN = 0; | |
currentM = 0; | |
} | |
int main() { | |
/*clock_t start,end; | |
start = clock(); */ | |
ios_base::sync_with_stdio(false); | |
cin >> N >> M >> D; | |
for (int i = 0; i < N; i++) { | |
v.push_back(v2); | |
for (int j = 0; j < M; j++) { | |
int input; | |
cin >> input; | |
v[i].push_back(input); | |
} | |
} | |
for (int i = 0; i < M; i++) { | |
for (int j = 1; j < N; j++) { | |
for (int k = 0; k < M; k++) { | |
search(locationN,i,j,k); | |
} | |
} | |
} | |
reset(); | |
while (locationN != N-1) { | |
for (int i = locationN+1; i < N; i++) { //탐색 대상이 되는 N | |
for (int j = 0; j < M; j++) { //탐색 대상이 되는 M | |
search(locationN,locationM,i,j); | |
} | |
} | |
reset(); | |
} | |
cout << score; | |
/* | |
end = clock(); | |
double result = (double)(end-start); | |
cout << '\n' << result << endl; | |
*/ | |
return 0; | |
} |
제 시도가 늘 정답일 순 없고,
접근 방법이 잘못되었다면 어떻게 접근했고 왜 잘못되었는지 파악하는 것도 중요하다고 생각하여
실패 답안을 남겨둡니다.
'알고리즘, 문제해결 > 알고리즘 문제풀이' 카테고리의 다른 글
[백준 17501번] 수식 트리 (0) | 2020.11.08 |
---|---|
[백준 17498번] 폴짝 게임 (0) | 2020.11.07 |
[백준 1339번] 단어 수학 (0) | 2020.11.06 |
[백준 17497번] 계산기 (0) | 2020.11.05 |
[백준 1202번] 보석 도둑 (0) | 2020.10.12 |
댓글