본문 바로가기

알고리즘/백준

백준 18429 근손실 - dfs와 백트래킹 (c++)

728x90

https://www.acmicpc.net/problem/18429

 

18429번: 근손실

웨이트 트레이닝을 좋아하는 어떤 대학원생은, 현재 3대 운동 중량 500의 괴력을 소유하고 있다. 다만, 하루가 지날 때마다 중량이 K만큼 감소한다. 예를 들어 K=4일 때, 3일이 지나면 중량이 488로 감소하게 된다. 따라서 운동을 하지 않고, 가만히 있다면 매일매일 중량이 감소할 뿐이다. 다행히도 이 대학원생은 N개의 서로 다른 운동 키트를 가지고 있다. 이 대학원생은 하루에 1개씩의 키트를 사용하며, 매일 어떤 키트를 사용할 지는 마음대로 결정할

www.acmicpc.net

백트래킹을 하면서, 근손실이 나지않는 조건 하에서 dfs를 끝까지 진행한 경우에 결과에 +1씩 해주면 되는 문제였다.

백트래킹의 대표적인 문제로는 n queen 문제가 있다. n queen문제는 체스판에 퀸이 서로를 잡을수 있는 위치에 있을 수 있냐 업냐를 판단하는 함수를 따로 만든 후에 dfs를 진행하면서 백트래킹을 해야한다. 하지만 이 문제는 따로 근손실이 난다 안난다 하는 함수를 굳이 만들 필요없이 500을 넘냐 안넘냐만 판단하면 되기 때문에, n queen보다는 간단한문제인 것 같다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
using namespace std;
int N,K;
int gain[51];
int answer = 0;
bool visited[51];
int weight = 500;
 
void dfs(int count){
    if(count==N) {
        answer++;
    }
    else{
        for(int i=0; i<N; i++){
            if(!visited[i]){
                visited[i]=true;
                if(weight+gain[i]>=500){
//                    cout<<i;
                    weight += gain[i];
                    dfs(count+1);
                    weight -= gain[i];
                    visited[i]=false;
                }
                else
                    visited[i]=false;
 
            }
        }
    }
}
 
 
int main(void){
    cin>>N>>K;
    for(int i=0; i<N; i++){
        cin>>gain[i];
        gain[i]-=K;
    }
    dfs(0);
    cout<<answer;
 
}