Posts List

2018년 6월 9일 토요일

Permutation

m개의 main dish 와 n개의 side dish 가 있다.
main dish 와 side dish 는 중복선택 불가하다고 할 때, main dish 와 side dish 로 가능한 모든 조합을 구해보자.

예를 들어, 2개의 main dish와 3개의 side dish가 있다면,
경우의 수는 3x2 = 6 이고, 모든 경우의 수는
{(m1, s1), (m2, s2)}
{(m1, s1), (m2, s3)}
{(m1, s2), (m2, s1)}
{(m1, s2), (m2, s3)}
{(m1, s3), (m2, s1)}
{(m1, s3), (m2, s2)}
for (int m1=s1; m1<=s3; m1++)
    for (int m2=s1; m2<=s3; m2++)
        if (m1==m2) continue;
        printf("(m1, %d), (m2, %d)", m1, m2)

3개의 main dish와 3개의 side dish가 있다면, 3x2x1 = 6가지 경우이며,
{(m1, s1), (m2, s2), (m3, s3)}
{(m1, s1), (m2, s3), (m3, s2)}
{(m1, s2), (m2, s1), (m3, s3)}
{(m1, s2), (m2, s3), (m3, s1)}
{(m1, s3), (m2, s1), (m3, s2)}
{(m1, s3), (m2, s2), (m3, s1)}
for (int m1=s1; m1<=s3; m1++)
    for (int m2=s1; m2<=s3; m2++)
        if (m1==m2) continue;
        for (int m3=s1; m3<=s3; m3++)
            if (m3==m1 || m3==m2) continue;
            printf("(m1, %d), (m2, %d), (m3, %d)", m1, m2, m3)

for loop 로 구현하면 m,n 값에 맞게 일일이 iterator 변수를 추가해주어야 하는 문제가 있음.
main dish2는 main dish1과 조합을 이루지 않은 side dish 중 한 개,
main dish3은 main dish1, main dish2와 조합을 이루지 않은 side dish 중 한 개 이므로
재귀로 구현해보면, 아래와 같음. (좀 더 간결하게 되려나)

#include <stdio.h>

void select(int id, int selected[3])
{
    if (id == 2) {
        int temp;
        for (int iter = 0; iter < 3; iter++) {
            if (selected[iter] == -1) {
                temp = iter;
                break;
            }
        }
        selected[temp] = id;
        for (int iter = 0; iter < 3; iter++) {
            printf("(%d %d) ", iter, selected[iter]);
        }
        printf("\n");
        selected[temp] = -1;
        return;
    }
    for (int iter = 0; iter < 3; iter++) {
        if (selected[iter] == -1) {
            selected[iter] = id;
            select(id+1, selected);
            selected[iter] = -1;
        }
    }
}

int main()
{
    int selected[3] = {-1, -1, -1};
    select(0, selected);
    return 0;
}

printf 부분 대신 다른 로직을 넣으면 permutation 경우의 수마다 특정 처리를 하는게 가능해보임. 예를 들면, main dish + side dish 조합 중 가장 가격이 싼 경우를 구할 때, printf 대신에 lowest_total_price 를 갱신하도록 하면 됨.

일단 코드를 좀 더 간결하게 하는 게 필요함.
또한 재귀 깊이가 어느 정도까지 가능한 지도 업데이트 할 것.

댓글 없음:

댓글 쓰기