티스토리 뷰

#문제

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


#풀이

이 문제의 경우, 백트래킹을 이용하여 팀을 나누고 그 중에서 2명을 뽑아내는 식으로 하였습니다.


해당 문제를 어디서 많이 보았다 했는데 예전에 풀었던 것과 거의 비슷했습니다.

혹시나 하여 링크를 달아드립니다.

[BOJ 스타트와 링크] : https://www.acmicpc.net/problem/14889

해당 문제와 거의 비슷하지만 한가지 조건이 추가가 되었습니다.

바로 전체 인원이 홀수일 수  있다는것!


해당 조건 때문에 뽑을때 고려해야 할 개수가 늘어났습니다... :(

전체 인원이 5명일때, 스타트팀이 2명 링크팀이 3명 또는 스타트팀이 3명 링크팀이 2명일 경우로 나누어지게 됩니다.

따라서 홀수일 때는 2명과 3명 모두 뽑아주어야 합니다.


백트래킹을 이용하여 전체 인원을 2개로 나누며, 이를 또 2명씩 뽑도록 하였습니다.

혹시 백트래킹을 모르신다면 구글링을 한번 하고 오시는것이 이해에 도움이 될꺼같습니다. :)


#코드

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
 
//스탯정보
int stat[20][20];
//사람마다 팀 정보 -> 0 : 스타트팀 , 1 : 링크팀
int team[21];
int N;
int ans = 987654321;
 
//선택된 팀에 따라 2명씩 뽑기
int selectTwoPeople(int teamNum, int d, vector<int> man, int n){
    int result = 0;
    if(d == 2){
        //1,2를 뽑았을때 [1,2]와 [2,1]은 한번에 알 수 있다.
        //그렇기에 굳이 밑에서 1부터 돌리지 않아도 된다.
        return stat[man[0]-1][man[1]-1+ stat[man[1]-1][man[0]-1];
    }
    //어떤 팀에서 2명을 뽑기(백트래킹)
    for(int i = n; i <= N; i++){
        if(team[i] == teamNum){
            man.push_back(i);
            //해당 팀의 모든 스탯을 더해준다.
            result += selectTwoPeople(teamNum, d+1, man, i+1);
            man.pop_back();
        }
    }
    //다 더한 스탯을 넘겨준다.
    return result;
}
 
// isOdd = 1 홀수일때, isOdd = 0 짝수일때
void makeTeam(int num, int d, int isOdd){
    if(num == N/2 + isOdd){
        vector<int> teamStart;
        vector<int> teamLink;
        int statStart = selectTwoPeople(10, teamStart, 1);
        int statLink = selectTwoPeople(00, teamLink, 1);
        //팀간 스탯 차이를 최종 답과 비교. 더 작은 값을 넣는다.
        if(ans > abs(statStart - statLink)){
            ans = abs(statStart - statLink);
        }
    }
    //팀 뽑기(백트래킹)
    for(int i = d; i <= N; i++){
        if(team[i] == 1) continue;
        team[i] = 1;
        makeTeam(num+1, i+1, isOdd);
        team[i] = 0;
    }
}
 
int main(){
    cin >> N;
    for(int i = 0; i < N; i++){
        for(int j = 0; j < N; j++){
            cin >> stat[i][j];
        }
    }
    //홀수일때는 둘중 한팀은 한명이 더 많다.
    //따라서 양 팀다 한명씩 더 많은 경우의 수를 따져봐야한다.
    makeTeam(0,1,0);
    if(N%2 == 1){
        makeTeam(0,1,1);
    }
    cout << ans << endl;
    return 0;
}
 
cs


'알고리즘 문제 풀이 > BOJ' 카테고리의 다른 글

[BOJ 16197] 두 동전  (1) 2019.02.15
[BOJ 3019] 테트리스  (0) 2019.02.14
[BOJ 1107] 리모컨  (1) 2019.02.12
[BOJ 3568] iSharp  (0) 2019.02.11
[BOJ 15662] 톱니바퀴(2)  (0) 2019.02.10
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
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
글 보관함