java 조합관련 문제 질문 드립니다.

조회수 523회

n(짝수)과 n명의 코인개수를 입력받아 두 팀으로 나누고 두 팀의 코인개수의 최소값을 출력하고자 합니다. 6과 10 20 30 40 30 20을 입력하면 값이 10으로 출력되어야 합니다.

먼저 팀을 나눠야 할 것 같아서 조합으로 다 출력해보았습니다.

'''

public static void main(String[] args) {
    // TODO Auto-generated method stub

    Scanner sc = new Scanner(System.in);

    int n = sc.nextInt();

    int[] s = new int[n];
    int[] bucket = new int[n/2];

    for(int i = 0; i < s.length; i++)
        s[i] = sc.nextInt();

   pick(s, n, bucket, n/2, n/2);
}
public static void pick(int[] item, int itemSize, int[] bucket, int bucketSize, int k)
{//조합

    int i, total = 0, sum = 0;
    int smallest, lastIndex, min = 999999;

    for(i = 0; i < itemSize; i++) {
        total += item[i];
    }

    if ( k == 0 ) // trivial case
    {
        int team = 0;
        for(i = 0; i < bucketSize; i++) {
            System.out.printf("%s ", item[bucket[i]]);
            sum += item[bucket[i]];
        }
        System.out.println(sum);
        return;
    }
    lastIndex = bucketSize - k - 1;

    if(bucketSize == k)
        smallest = 0;
    else
        smallest = bucket[lastIndex]+1;

    for(i = smallest; i < itemSize; i++)
    {
        bucket[lastIndex+1] = i;
        pick( item, itemSize, bucket, bucketSize, k-1 );
    }
}'''

이 코드를 구현하면 n/2명의 코인과 n/2명의 코인의 합의 경우의 수가 출력됩니다.

두 팀의 코인개수의 최소값을 출력하기 위해서는 이 중 하나가 선택되어야 할 텐데 그 부분에서 막혔습니다.

item값의 total을 구해서 sum을 빼면 다른팀의 코인의 합이 나오니 sum과 다른팀의 코인의 합의 차를 구해서 중복되는 값을 제외하고 배열에 넣어 최소값을 구해 반환하면 될 것 같다고 생각했습니다. 그치만 이를 구현하기가 너무 어렵더라구요.

제가 생각한 논리가 잘못된것인지 구현을 못하는 건지 잘 모르겠습니다.

코드를 구현해주실 수 있으시다면 너무 감사드리겠습니다. 방향성을 제시해주셔도 좀 더 생각해보고 다시 풀어보겠습니다. 감사합니다.

  • 왜 10이 나와요? 이해가 잘 안되는데.. 누구는 코인10개 누구는 코인20개 뭐 이렇게 갖고있는 6명이 있고 그걸 세 사람씩 두 팀으로 나누는 거잖아요? 그러면 한팀이 가질수 있는 최소 코인은 10+20+20=50개 아닌지? 엽토군 2019.6.21 20:14
  • 그 팀끼리의 차의 최소값을 구하는 거에요!! (10+30+40) - (20+20+30) = 10 이런식으로요! 김재아 2019.6.21 21:05

1 답변

  • 이건 수학 문제로서의 풀이가 필요할 것 같은데 이하는 그냥 막연히 생각난 거니까 검증을 해 주세요.

    1. 만약 이 사람들이 공산당이라서 6명이 전부 3코인씩을 갖고 있다면 팀을 어떻게 나누든 두 팀이 소지한 코인은 최소 0코인 차이가 나고, 최대 차이도 0코인입니다.
    2. 만약 이 사람들이 네오리버럴 시장경제 사회라서 1명만 407코인을 갖고 있고 나머지 5명이 3코인씩을 갖고 있다면, 그 갑부 1명은 한쪽 팀에만 배치될 수 있으므로, 최소 차 = 최대 차 = 407 - 3 = 404코인이 됩니다.
    3. 만약 2명이 4코인씩을 갖고 있고 나머지 4명이 3코인씩을 갖고 있다면, 그 2명이 양쪽 팀에 1명씩 배치되었을 때 두 팀의 코인의 차는 0이 되고 그렇지 않을 때는 최대값인 2코인이 되겠지요.

    대충 이런 식이라면 중간값을 기준으로 어림잡는 계산이 가능할 것 같네요.

    1. 6명이 가진 코인의 평균값을 구한다.
    2. 그 평균값에 가장 근접한 놈 하나를 찾아 이쪽 팀에 넣는다. (여기서 '근접'이란 절대값을 기준으로 한다.)
    3. 그 다음으로 근접한 놈을 찾아 저쪽 팀에 넣는다.
    4. 그 다음으로 근접한 놈을 찾아 이쪽 팀에 넣는다.
    5. 그 다음으로 근접한 놈을 찾아... 생략
    6. 이렇게 6명을 모두 2팀으로 나누면, 지금까지의 논의에 의해 필연적으로, 이쪽 팀과 저쪽 팀의 코인의 차는 최소가 된다.
    7. 그러므로 지금 상태에서 두 팀의 코인의 차를 구하면 답이 된다. 끝.

    제가 문과라서 이 풀이가 틀렸을 수 있으니 한번 스스로 검증을 해보시고 부족한 부분이나 잘못된 부분은 바로잡으신 다음 코딩하시면 될 거 같습니다. 지금 문득 드는 생각은 '분명히 이런 종류의 문제를 부르는 용어나 주제가 있을 것 같다'는 건데 그것까지는 잘 모르겠네요.

    • 아 제가 문제 조건을 빼먹었네요.. 두 팀의 인원 수는 같습니다!! 그래도 답변 감사드려요! 김재아 2019.6.21 22:20

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)