[c++] μ•Œκ³ λ¦¬μ¦˜ κ°œλ…κ³΅λΆ€ :: μˆœμ—΄κ³Ό μ‘°ν•© (μ½”λ“œ, next_permutation 이용, 직접 κ΅¬ν˜„)

μˆœμ—΄κ³Ό μ‘°ν•©

μˆœμ—΄

μ •μ˜

μˆœμ—΄μ€ 쀑볡없이 n개 쀑 r개λ₯Ό 뽑아 μˆœμ„œλ₯Ό μ •ν•΄ λ‚˜μ—΄ν•˜λŠ” κ²½μš°μ΄λ‹€. μœ„μ˜ 그림처럼 A, B, C 세가지 μ›μ†Œκ°€ μžˆμ„ λ•Œ, 2개λ₯Ό 뽑아 μˆœμ„œλ₯Ό μ •ν•˜λŠ” 것을 3P2라고 ν•œλ‹€. μ•„λž˜μ™€ 같은 경우의 μˆ˜κ°€ λ‚˜μ˜€λ―€λ‘œ 총 6가지 이닀.

μˆœμ—΄μ€ P(Permutation)둜 ν‘œν˜„ν•˜λ©° 식은 λ‹€μŒκ³Ό κ°™λ‹€.
$$
{}n\mathrm{P}{r} = \frac{n!}{(n-r)!}
$$

쀑볡 μˆœμ—΄μ΄λΌλŠ” νŠΉλ³„ν•œ κ²½μš°λŠ” μˆœμ—΄ 쀑 같은 μ’…λ₯˜μ˜ 것을 λ‹€μ‹œ 뽑을 수 μžˆλŠ” 경우λ₯Ό λ§ν•œλ‹€.

쀑볡 μˆœμ—΄μ€ Π둜 ν‘œν˜„ν•˜λ©° 식은 λ‹€μŒκ³Ό κ°™λ‹€.
$$
{n}\mathrm{\pi}{r} = n^r
$$

 

κ΅¬ν˜„

μˆœμ—΄

// 직접 κ΅¬ν˜„
void swap(vector<int>& set, int a, int b){
    int tmp = set[a];
    set[a] = set[b];
    set[b] = tmp;
}

void permutation(vector<int>& set, int size, int n, int r){
    if(size==r){
        for(int i=0; i<size; i++)
            cout << set[i] << " ";
        cout << endl;
        return;
    }
    for(int i=size; i<n; i++){
        swap(set, i, size);
        permutation(set, size+1, n, r);
        swap(set, i, size);
    }
}

int main()
{
    vector<int> set;
    set.push_back(1);
    set.push_back(2);
    set.push_back(3);

    combination(set, 0, 3, 2);

    return 0;
}
// next_permutation 이용
void permutation(vector<int>& set, int n, int r){
    do{
        for(int i=0; i<r; i++)
            cout << set[i] << " ";
        cout << endl;
    }while(next_permutation(set.begin(), set.end()));
}

int main()
{
    vector<int> set;
    set.push_back(1);
    set.push_back(2);
    set.push_back(3);

    combination(set, 3, 2);

    return 0;
}

 

쀑볡 μˆœμ—΄

void repeatedPermutation(vector<int>& set, vector<int>&tmp, int size, int n, int r){
    if(size==r){
        for(int i=0; i<size; i++)
            cout<< tmp[i] << " ";
        cout << endl;
        return;
    }
    for(int i=0; i<n; i++){
        tmp[size] = set[i];
        permutation(set, tmp, size+1, n, r);
        tmp[size] = 0;
    }
}

int main()
{
    vector<int> set;
    set.push_back(1);
    set.push_back(2);
    set.push_back(3);
    vector<int>tmp(3);

    repeatedPermutation(set,tmp,0, 3, 2);

    return 0;
}

쀑볡 μˆœμ—΄μ„ κ΅¬ν•˜κΈ° μœ„ν•΄μ„œ tmpλΌλŠ” vectorλ₯Ό ν•˜λ‚˜ 더 μ‚¬μš©ν•˜μ˜€λ‹€. λ”°λ‘œ vectorλ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šκ³ λ„ κ΅¬ν˜„ν•  수 μžˆλŠ” 방법이 μžˆμ„κΉŒ?

 

μ‘°ν•©

μ •μ˜

쑰합은 쀑볡없이 n개 쀑 r개λ₯Ό μˆœμ„œμ— 상관없이 λ½‘λŠ” κ²½μš°μ΄λ‹€. μœ„μ˜ 그림처럼 A, B, C 세가지 μ›μ†Œκ°€ μžˆμ„ λ•Œ, 2개λ₯Ό μˆœμ„œμ— 상관없이 λ½‘λŠ” 것을3C2라고 ν•œλ‹€. μ•„λž˜μ™€ 같은 경우의 μˆ˜κ°€ λ‚˜μ˜€λ―€λ‘œ 총 3가지이닀.

쑰합은 C(Combination)둜 ν‘œν˜„ν•˜λ©° 식은 λ‹€μŒκ³Ό κ°™λ‹€.
$$
{n}\mathrm{C}{r} = \frac{{n}\mathrm{P}{r}}{r!} \ ({n}\mathrm{C}{0},\ {n}\mathrm{C}{n}은\ 0)
$$

$$
{n}\mathrm{C}{r} = {n-1}\mathrm{C}{r-1}+{n-1}\mathrm{C}{r}
$$
쀑볡 μ‘°ν•©μ΄λΌλŠ” νŠΉλ³„ν•œ κ²½μš°λŠ” μ‘°ν•© 쀑 같은 μ’…λ₯˜μ˜ 것을 λ‹€μ‹œ 뽑을 수 μžˆλŠ” 경우λ₯Ό λ§ν•œλ‹€.

쀑볡 쑰합은 H둜 ν‘œν˜„ν•˜λ©° 식은 λ‹€μŒκ³Ό κ°™λ‹€.
$$
{n}\mathrm{H}{r} = {n+r-1}\mathrm{C}{r}
$$

$$
{n}\mathrm{H}{r} = {n}\mathrm{H}{r-1} +{n-1}\mathrm{H}{r}
$$

 

κ΅¬ν˜„

μ‘°ν•©

// 직접 κ΅¬ν˜„
void swap(vector<int>& set, int a, int b){
    int tmp = set[a];
    set[a] = set[b];
    set[b] = tmp;
}

void combination(vector<int>& set, int idx, int size, int n, int r){
    if(size==r){
        for(int i=0; i<size; i++)
            cout << set[i] << " ";
        cout << endl;
        return;
    }
    for(int i = idx; i<n; i++){
        swap(set, i, size);
        combination(set, i+1, size+1, n, r);
        swap(set, i, size);
    }
}

int main()
{
    vector<int> set;
    set.push_back(1);
    set.push_back(2);
    set.push_back(3);

    combination(set, 0, 0, 3, 2);

    return 0;
}
// next_permutation 이용
void combination(vector<int>& set, vector<int>& tmp, int n, int r){
    do{
        for(int i=0; i<n; i++){
            if(tmp[i]==1)
                cout << set[i] << " ";
        }
        cout << endl;
    }while(next_permutation(tmp.begin(), tmp.end()));
}

int main()
{
    vector<int> set;
    set.push_back(1);
    set.push_back(2);
    set.push_back(3);

    vector<int> tmp;
    tmp.push_back(0);
    tmp.push_back(1);
    tmp.push_back(1);
    // 주의!! 0, 1, 1 μ˜€λ¦„μ°¨μˆœ μˆœμ„œλ‘œ 써야 next_permutation이 μž‘μš©ν•œλ‹€.
    // μ•„λ‹ˆλ©΄ λ‚΄λ¦Όμ°¨μˆœ μ •λ ¬ ν›„ prev_permutation도 κ°€λŠ₯

    combination(set, tmp, 3, 2);

    return 0;
}

 

쀑볡 μ‘°ν•©

void repeatedCombination(vector<int>& set, vector<int>& tmp, int size, int index, int n, int r){
    if(size==r){
        for(int i=0; i<size; i++)
            cout << tmp[i] << " ";
        cout << endl;
        return;
    }

    for(int i=index; i<n; i++){
        tmp[size] = set[i];
        repeatedCombination(set, tmp, size+1, i, n, r);
    }
}

int main()
{
    vector<int> set;
    set.push_back(1);
    set.push_back(2);
    set.push_back(3);

    vector<int> tmp(3);

    repeatedCombination(set, tmp, 0, 0, 3, 2);

    return 0;
}

 

κ΄€λ ¨ 문제

Gaaaaaaaaaarden

λ°˜μ‘ν˜•