PS

백준 15661. 링크와 스타트

tose33 2021. 7. 29. 13:42

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

 

15661번: 링크와 스타트

첫째 줄에 N(4 ≤ N ≤ 20)이 주어진다. 둘째 줄부터 N개의 줄에 S가 주어진다. 각 줄은 N개의 수로 이루어져 있고, i번 줄의 j번째 수는 Sij 이다. Sii는 항상 0이고, 나머지 Sij는 1보다 크거나 같고, 100

www.acmicpc.net

 

분명 이전에 푼 문제같은데 안풀어져 있어서 찾아봤더니 이전에 푼 문제는 14889.스타트와 링크였다.

이전에 푼 문제와 다른 점은 이전꺼는 모인 인원수가 무조건 짝수고 정학히 팀을 반으로 나누는 것이었고

이번 문제는 두 팀의 인원수는 서로 다를수 있다는 것.

 

1. 1명 부터 n-1명 까지 뽑는 조합을 dfs로 구한다.

  n=4라면 

  1명 뽑는 조합: {1}, {2}, {3}, {4}

  2명 뽑는 조합: {1,2}, {1,3}, {1,4} ... 

  3명 뽑는 조합: {1,2,3}, {1,2,4}... 

뽑히지 않은 수가 다른 팀이다.

 

2. 이렇게 팀이 정해졌으니, 이제 두 팀의 점수를 구하고 차를 구한다.

 

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int n;
int ans = 999999999;
int S[21][21];

vector<int> member;
bool mark[21];

int CalculateTeamScore(vector<int> v)
{
    // 팀 점수 계산
    int teamScore = 0;
    for(int i = 0; i < v.size(); i++)
    {
        for(int j = 0; j < v.size(); j++)
        {
            // 자기자신과의 계산은 제외
            if(j == i) continue;
            teamScore += S[v[i]][v[j]];
        }
    }

    return teamScore;
}

void Calculate()
{
    vector<int> link, start;
    for(int i = 0; i < n; i++)
    {
        if(mark[i])
            link.push_back(member[i]);
        else
            start.push_back(member[i]);
    }

    int linkScore = CalculateTeamScore(link);
    int startScore = CalculateTeamScore(start);

    ans = min(ans, abs(linkScore - startScore));
}

// howMany명의 조합 뽑음
void dfs(int idx, int depth, int howMany)
{
    if(depth == howMany)
    {
        // 팀 뽑은 상태에서 팀의 점수 계산
        Calculate();

        return;
    }

    for(int i = idx; i < n; i++)
    {
        if(mark[i]) continue;
        mark[i] = true;

        dfs(i, depth+1, howMany);

        mark[i] = false;
    }
}

int main()
{
    // inputs
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= n; j++)
        {
            cin >> S[i][j];
        }
    }

    // 1,2,3,...,n
    for(int i = 1; i <= n; i++)
        member.push_back(i);

    for(int i = 1; i < n; i++)
    {
        dfs(0, 0, i);
    }

    cout << ans;
}