[C++] 백준 14889번: 스타트와 링크

2022. 9. 26. 22:42·problem solving/백준

🔗 문제

14889번: 스타트와 링크

 

14889번: 스타트와 링크

예제 2의 경우에 (1, 3, 6), (2, 4, 5)로 팀을 나누면 되고, 예제 3의 경우에는 (1, 2, 4, 5), (3, 6, 7, 8)로 팀을 나누면 된다.

www.acmicpc.net

 

🖍 풀이

 

어떻게 모든 경우의 수를 돌도록 함수를 짤지 고민만 하면 풀 수 있다.

 

이 문제에서는 팀원을 반으로 갈라야 한다. N이 6명이면 3명의 모일 수 있는 모든 조합을 구해야한다.

그렇다면 팀원을 N/2명 모일 때까지 재귀함수를 호출하도록 작성해준다.

N/2명이 모이면 능력치 차이를 구하고 다시 되돌아가 조합하지 않았던 팀원에 접근한다.

 

  1. 팀원을 한명씩 모은다.
    1. 팀원이 다 모였다.
      1. 능력치 계산을 하고 2번으로 간다.
    2. 팀원이 다 모일 때까지 반복
  2. 맨 마지막에 넣었던 팀원을 빼고 그 다음 팀원을 넣는다.
    1. (예시) 1, 2, 3 탐색 후 1, 2, 4 탐색
  3. 반복문에 int i=idx 조건을 달아 중복 조합을 피할 수 있다.
    1. (예시) (1,2,4)나 (1, 4, 2)는 같은 팀으로 또 탐색할 필요가 없다.  

 

void solve(int depth, int idx) // 팀원 수, 다음 탐색 시작할 인덱스
{
    // 팀 다 모았다. 
    if(depth == N/2)
    {
        // (능력치 구하기)
        return;
    }
		
    //팀원이 부족하다.
    for(int i=idx; i<N; ++i) // i = idx부터 시작해 중복 조합 제거
    {
        if(!teamed[i])
        {
            teamed[i] = true;
            solve(depth+1, i+1); // 팀원을 하나 추가해주고, 마지막으로 넣은 팀원 다음부터 탐색
            teamed[i] = false;
        }
    }
    
    return ;
}

 

채점 결과를 보니 30ms 이하 시간으로 푼 사람들이 있습니다. 

그런 풀이 방법을 아시는 분은 댓글로 공유 부탁드려요.

 

 

💾  소스

#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
const int MAX = 21;

int N;
int ability[MAX][MAX];
bool teamed[MAX];
int answer = 1e9;

void solve(int depth, int idx)
{
    if(depth == N/2)
    {
        int start=0, link=0;
        std::vector<int> starts;
        std::vector<int> links;
        
        for(int i=0; i<N; ++i)
        {
            if(teamed[i])
                starts.push_back(i);
            else
                links.push_back(i);
        }
        
        for(int i=0; i<N/2; ++i)
        {
            for(int j=i+1; j<N/2; ++j)
            {
                start += ability[starts[i]][starts[j]] + ability[starts[j]][starts[i]];
                link += ability[links[i]][links[j]] + ability [links[j]][links[i]];
            }
        }
        //std::cout << "start / link : " << start << " / " << link << std::endl;

        answer = std::min(answer, std::abs(start - link));
        return;
    }

    for(int i=idx; i<N; ++i)
    {
        if(!teamed[i])
        {
            teamed[i] = true;
            solve(depth+1, i);
            teamed[i] = false;
        }
    }
    
    return ;
}

int main()
{
    std::cin >> N;
    for(int i=0; i<N; ++i)
        for(int j=0; j<N; ++j)
            std::cin >> ability[i][j];
    
    solve(0, 0);
    
    std::cout << answer;
    
    return 0;
}
저작자표시 비영리 변경금지 (새창열림)
'problem solving/백준' 카테고리의 다른 글
  • [C++] 백준 1189번: 컴백홈
  • [C++] 백준 2447번: 별 찍기 - 10
  • [C++] 백준 17509번: And the Winner Is... Ourselves!
  • [C++] 백준 1493번: 박스 채우기*
u1qns
u1qns
http://github.com/u1qns
  • u1qns
    개발 블로그
    u1qns
  • 전체
    오늘
    어제
    • 분류 전체보기 (173) N
      • 회고 (1)
      • programming (17)
        • 개념 정리 (6)
        • CI CD (1)
        • 트러블 슈팅 (0)
        • 환경설정 및 팁 (7)
      • problem solving (155) N
        • 개념 정리 (3)
        • 백준 (129) N
        • SWEA (15)
        • 프로그래머스 (4)
  • 블로그 메뉴

    • 홈
    • 방명록
  • 링크

    • 깃허브
  • 공지사항

  • 인기 글

  • 태그

    완전탐색
    POW
    투포인터
    삼성청년SW아카데미
    DFS
    cpp
    백준
    boj
    cmath
    되추적
    미해결
    BFS
    SSAFY
    HELLOSSAFY
    그리디
    DP
    구현
    SSAFY수료식
    C++
    SWEA
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
u1qns
[C++] 백준 14889번: 스타트와 링크
상단으로

티스토리툴바