프로그래밍/알고리즘
Softeer-연습문제-나무 조경(C++)
Sechan Oh
2024. 3. 23. 14:56
문제 링크 : https://softeer.ai/practice/7594
난이도 : Lv.3
문제 개요 :
나무를 2개씩 묶은 후 묶은 나무들의 키 합의 최댓값 구하기
경우의 수가 별로 없어서 브루트포스로 해결했다.
#include<iostream>
#include<vector>
using namespace std;
bool check(const vector<vector<int>> selected, const int row, const int col){
for(int i=0; i<selected.size(); i++){
if(selected[i][0] == row && selected[i][1] == col){
return false;
}
}
return true;
}
void calculate(vector<vector<int>> map, vector<vector<int>> &selected, int &max_value){
const int n = map.size();
if(selected.size() == 8){
int result = 0;
for(int i=0; i<selected.size(); i++){
result += map[selected[i][0]][selected[i][1]];
}
selected.pop_back();
selected.pop_back();
if(max_value < result){
max_value = result;
}
return;
}
for(int j=0; j < (n-1)*n*2; j++){ // (n-1)*n*2 가지 경우의 수
if(j < (n-1)*n){
int row = j / n;
int col = j % n;
if(check(selected, row, col) && check(selected, row+1, col)){
selected.push_back({row, col});
selected.push_back({row+1, col});
calculate(map, selected, max_value);
}
}
else{
int row = (j - (n-1)*n) % n;
int col = (j - (n-1)*n) / n;
if(check(selected, row, col) && check(selected, row, col+1)){
selected.push_back({row, col});
selected.push_back({row, col+1});
calculate(map, selected, max_value);
}
}
}
if(selected.size() > 0){
int result = 0;
for(int i=0; i<selected.size(); i++){
result += map[selected[i][0]][selected[i][1]];
}
selected.pop_back();
selected.pop_back();
if(max_value < result){
max_value = result;
}
return;
}
}
int main(int argc, char** argv)
{
int n;
scanf("%d", &n);
vector<vector<int>> map(n, vector<int>(n));
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
scanf("%d", &map[i][j]);
}
}
// 가로로 먼저 돌고
vector<vector<int>> selected;
int max_value = 0;
calculate(map, selected, max_value);
cout << max_value;
return 0;
}
문제 해결 방법
1. 나무들의 키를 map에 저장한다.
2. 묶은 나무의 위치(x, y값)를 selected에 저장한다.
3. 재귀함수를 돌면서 n * n에서 나무 2개를 묶는 경우의 수(n*(n-1)*2가지)를 for문으로 모두 확인한다. 이때, check함수를 통해 이미 골랐던 나무를 또 선택했는지 체크한다. 재귀함수의 종료조건은 4묶음을 모두 묶었거나, 모든 경우의 수를 다 확인하고 for문을 빠져나온 경우이다. 함수를 종료하기 전에는 마지막에 선택했던 1묶음을 취소하고 종료한다.
4. 최댓값을 max_value에 저장하고, 마지막에 이를 출력한다.