ABOUT ME

Carpe Diem, Seize the day

Today
Yesterday
Total
  • [백준/BOJ] 12869번 뮤탈리스크 (C++)
    알고리즘 문제풀이/백준 2021. 2. 19. 23:38

    www.acmicpc.net/problem/12869

     

    12869번: 뮤탈리스크

    1, 3, 2 순서대로 공격을 하면, 남은 체력은 (12-9, 10-1, 4-3) = (3, 9, 1)이다. 2, 1, 3 순서대로 공격을 하면, 남은 체력은 (0, 0, 0)이다.

    www.acmicpc.net

    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();
    }

    댓글

Designed by Tistory.