-
[백준/BOJ] 12869번 뮤탈리스크 (C++)알고리즘 문제풀이/백준 2021. 2. 19. 23:38
DP 유형의 문제입니다.
처음에 단순히 문제의 입력값의 크기만 보고 BFS로 판단하여 문제를 풀다가 메모리 초과가 발생했습니다. 그래서 Top-Down 방식으로 접근하여 SCV의 체력이 음수가 되는 경우 인자를 0으로 바꿔 다시 재귀 탐색 처리를 해주고, 최소값을 메모이제이션을 통해 저장 후, 리턴하였습니다.
#include <iostream> #include <vector> #include <cstring> using namespace std; int a[3], n; int dp[61][61][61]; // SCV의 체력이 a, b, c인 상태에서 모두 파괴하기 위한 최소 공격 횟수 int DFS(int a, int b, int c) { if(a < 0) return DFS(0, b, c); if(b < 0) return DFS(a, 0, c); if(c < 0) return DFS(a, b, 0); if(dp[a][b][c] != -1) return dp[a][b][c]; if(a == 0 && b == 0 && c == 0) return 0; dp[a][b][c] = 2147000000; dp[a][b][c] = min(dp[a][b][c], DFS(a - 9, b - 3, c - 1) + 1); dp[a][b][c] = min(dp[a][b][c], DFS(a - 9, b - 1, c - 3) + 1); dp[a][b][c] = min(dp[a][b][c], DFS(a - 3, b - 9, c - 1) + 1); dp[a][b][c] = min(dp[a][b][c], DFS(a - 3, b - 1, c - 9) + 1); dp[a][b][c] = min(dp[a][b][c], DFS(a - 1, b - 9, c - 3) + 1); dp[a][b][c] = min(dp[a][b][c], DFS(a - 1, b - 3, c - 9) + 1); return dp[a][b][c]; } int main(void) { ios_base::sync_with_stdio(false); cin.tie(0); cin >> n; for(int i = 0; i < n; i++) { cin >> a[i]; } memset(dp, -1, sizeof(dp)); cout << DFS(a[0], a[1], a[2]); }
++
메모이제이션을 활용하면 BFS로도 해결 가능
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int dx[] = {-1, 0, 1, 0}; const int dy[] = {0, 1, 0, -1}; struct Info { int x, y, z; }; int t, n, m, k, sx, sy, ex, ey, x, y, z, answer, L, R; int a[3], visited[61][61][61]; int dmg[6][3] = { { 9, 3, 1 }, { 9, 1, 3 }, { 3, 9, 1 }, { 3, 1, 9 }, { 1, 9, 3 }, { 1, 3, 9 } }; vector<pair<int, int>> fire; int BFS() { queue<Info> q; q.push({ a[0], a[1], a[2] }); visited[a[0]][a[1]][a[2]] = 0; while(!q.empty()) { int x = q.front().x; int y = q.front().y; int z = q.front().z; q.pop(); if(x == 0 && y == 0 && z == 0) return visited[x][y][z]; for(int i = 0; i < 6; i++) { int nx = max(0, x - dmg[i][0]); int ny = max(0, y - dmg[i][1]); int nz = max(0, z - dmg[i][2]); if(visited[nx][ny][nz] == -1) { visited[nx][ny][nz] = visited[x][y][z] + 1; q.push({ nx, ny, nz }); } } } } int main() { //freopen("input.txt", "r", stdin); ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> n; for(int i = 0; i < n; i++) { cin >> a[i]; } memset(visited, -1, sizeof(visited)); cout << BFS(); }
'알고리즘 문제풀이 > 백준' 카테고리의 다른 글
[LeetCode] Best Time to Buy and Sell Stock (C++) (0) 2021.03.07 [백준/BOJ] 10422번 괄호 (C++) (0) 2021.02.22 [프로그래머스/Level 3] 기둥과 보 설치 (C++) (0) 2021.02.17 [백준/BOJ] 12886번 돌 그룹 (C++) (0) 2021.02.15 [백준/BOJ] 9251번 LCS (C++) (0) 2021.02.14