hyelie
hyelie
Hyeil Jeong
       
글쓰기    관리    수식입력
  • 전체보기 (495)
    • PS (283)
      • Algorithm (28)
      • PS Log (244)
      • Contest (6)
      • Tips (5)
    • Development (52)
      • Java (14)
      • Spring (23)
      • SQL (2)
      • Node.js (2)
      • Socket.io (3)
      • Study (4)
      • Utils (4)
    • DevOps (36)
      • Git (5)
      • Docker (4)
      • Kubernetes (2)
      • GCP (3)
      • Environment Set Up (8)
      • Tutorial (12)
      • Figma (2)
    • CS (74)
      • OOP (7)
      • OS (24)
      • DB (2)
      • Network (24)
      • Architecture (0)
      • Security (2)
      • Software Design (0)
      • Parallel Computing (15)
    • Project (15)
      • Project N2T (5)
      • Project ASG (0)
      • Project Meerkat (1)
      • Model Checking (7)
      • Ideas (2)
    • 내가 하고싶은 것! (34)
      • Plan (16)
      • Software Maestro (10)
      • 취준 (8)
hELLO · Designed By 정상우.
hyelie

hyelie

PS/Algorithm

2020/07/06 공부 - backtracking

 오늘은 backtrack 마지막 문제, 스타트와 링크를 풀었다.

 총 N명의 사람 중 N/2명을 고르는 것이므로 $_nC_{n/2}$ 만큼의 경우의 수를 봐 주어야 한다.

 총 1부터 8까지 사람이 있으면

 1 2 3 4
 1 2 3 5
 1 2 3 6
 1 2 3 7
 1 2 3 8
 1 2 4 5
 1 2 4 6
 1 2 4 7
 ...
 2 3 4 5
 2 3 4 6
 ...

 대충 이런식으로 조합 경우의 수가 정해지기 때문에, 제일 최근에 탐색한 사람 다음 사람부터 DFS를 실행했다.

 그리고 N이 짝수인 것은 보장되었기 때문에 depth가 N/2가 되면 점수 계산을 진행한다. 조금 더 깔끔한 코드도 존재할 수 있겠지만 아직 그 정도의 실력이 안 되는 것 같다.

 전체적인 구조는 다른 backtrack 문제들과 동일하다. depth가 일정 깊이에 도달하면 stop하고 점수를 계산한다. 안 그러면 내가 원하는 DFS를 진행한다. 위에 언급한 것처럼 '조합의 특성'을 코드로 생각하는 게 좀 어려웠다.

 

void DFS(vector<vector<int>>& stat, vector<bool>& people_in_start, int depth, int N, int& stat_difference, int recently_searched_people) {
    if (depth == N / 2) {
        int team_stat_start = 0;
        int team_stat_link = 0;
        vector<int> team_start;
        vector<int> team_link;
        for (int i = 0; i < N; i++) {
            if (people_in_start[i] == true) team_start.push_back(i);
            else team_link.push_back(i);
        }
        for (int i = 0; i < team_start.size(); i++) {
            for (int j = i + 1; j < team_start.size(); j++) {
                team_stat_start += stat[team_start[i]][team_start[j]];
                team_stat_start += stat[team_start[j]][team_start[i]];
            }
        }
        for (int i = 0; i < team_link.size(); i++) {
            for (int j = i + 1; j < team_link.size(); j++) {
                team_stat_link += stat[team_link[i]][team_link[j]];
                team_stat_link += stat[team_link[j]][team_link[i]];
            }
        }
        stat_difference = min(stat_difference, abs(team_stat_link-team_stat_start));
        return;
    }
    else {
        // DFS
        for (int i = recently_searched_people+1; i < N; i++) {
            people_in_start[i] = true;
            DFS(stat, people_in_start, depth + 1, N, stat_difference, i);
            people_in_start[i] = false;
        }
        // 처음에는 1부터 n/2까지, 그다음엔 1부터 n/2-1 + n/2+1, n/2+2, ...
        // 이 문이 생각보다 생각하기 어려웠음. 조합을 떠올리기
    }
}

 

 이제 입력받고 실행 함수를 적으면 끝일 것이다.

 

void solve() {
    int N;
    cin >> N;
    vector<vector<int>> stat(N, vector<int>(N));
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            cin >> stat[i][j];
        }
    }
    int stat_difference = 1000000000;
    vector<bool> people_in_start(N);

    DFS(stat, people_in_start, 0, N, stat_difference, 0);
    cout << stat_difference;
}

'PS > Algorithm' 카테고리의 다른 글

2020/07/08 공부 - dynamic programming  (0) 2022.06.21
2020/07/07 공부 - dynamic programming  (0) 2022.06.21
2020/07/06 공부 - dynamic programming  (0) 2022.06.21
2020/07/04 공부 - backtracking  (0) 2022.06.21
2020/07/02 공부 - backtracking  (0) 2022.06.21
    hyelie
    hyelie

    티스토리툴바