ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 백준 2407 (조합) c++
    백준 문제 2022. 8. 22. 13:51
    728x90

    문제

     

    2407번: 조합

    n과 m이 주어진다. (5 ≤ n ≤ 100, 5 ≤ m ≤ 100, m ≤ n)

    www.acmicpc.net

    n과 r을 입력받아 nCr 을 출력하면 되는 문제입니다. n과 r은 범위가 100까지 입니다.

    단순히 계산하게 되면 오버플로우가 발생합니다. 

    따라서 string 형으로 계산을 해줘야 합니다. 

    조합을 구하는 방식은 '파스칼의 삼각형' 방식을 이용해 문제를 해결하였습니다.

    nCr = (n-1)C(r-1) + (n-1)C(r) 입니다.

    먼저 위와 같은 방식으로 dp 형태로 nCr을 계산할 예정입니다.

    string arr[101][101]
    string combination(int n, int r) {
    	if (n == r || r == 0) //nCn =1 , nC0 = 1
    		return "1";
    
    	string& ans = arr[n][r]; 
    	if (ans != "") //이미 계산했던 dp이면 그대로 return
    		return ans;
    
    	return ans = cal(combination(n - 1, r - 1), combination(n - 1, r));
    	
    }

    모든 계산은 문자열로 이루어 집니다. 

     

    이제 점화식 arr[n][r] = arr[n-1][r-1] + arr[n-1][r] 을 위해 더하는 과정이 필요합니다.

    string cal(string st1, string st2) {
    	int sum = 0;
    	string result;
    	while (!st1.empty() || !st2.empty() || sum) {
    		if (!st1.empty()) {
    			sum += st1.back() - '0';
    			st1.pop_back();
    		}
    		if (!st2.empty()) {
    			sum += st2.back() - '0';
    			st2.pop_back();
    		}
    		result.push_back((sum % 10) + '0'); //일의자리 부터 push
    		sum /= 10;
    	}
    	reverse(result.begin(), result.end()); //일의 자리가 맨 앞이므로 reverse
    	return result;
    }

    문자열 2개를 합쳐주는 과정입니다. 일의 자리 부터 하나씩 %10을 계산해 일의자리 부터 서로 더해줘

    result에 넣어줍니다. 

    마지막에는 일의 자리가 맨앞에 있는 상태이므로 reverse를 해줘서 return하게 됩니다.


    전체 코드입니다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <string>
    #include <stack>
    #include <queue>
    #include <deque>
    #include <cmath>
    #include <map>
    #include <set>
    #include <tuple>
    #define MAX 2100000000
    #define inf LONG_MAX
    #define big(a, b) a > b ? a : b
    using namespace std;
    using ll = long long;
    using ull = unsigned long long;
    string arr[101][101];
    string combination(int n, int r);
    string cal(string st1, string st2);
    int main() {
        ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
        int n, r;
        cin >> n >> r;
     
        cout<< combination(n, r);
        
        
     
        return 0;
    }
    string combination(int n, int r) {
        if (n == r || r == 0)
            return "1";
     
        string& ans = arr[n][r];
        if (ans != "")
            return ans;
     
        return ans = cal(combination(n - 1, r - 1), combination(n - 1, r));
        
    }
    string cal(string st1, string st2) {
        int sum = 0;
        string result;
        while (!st1.empty() || !st2.empty() || sum) {
            if (!st1.empty()) {
                sum += st1.back() - '0';
                st1.pop_back();
            }
            if (!st2.empty()) {
                sum += st2.back() - '0';
                st2.pop_back();
            }
            result.push_back((sum % 10+ '0');
            sum /= 10;
        }
        reverse(result.begin(), result.end());
        return result;
    }
     
     
    cs

    '백준 문제' 카테고리의 다른 글

    백준 9465 (스티커) c++  (0) 2022.08.26
    백준 1629 (곱셈) c++  (0) 2022.08.26
    백준 14500 (테트로미노) c++  (0) 2022.08.21
    백준 9019 (DSLR) C++  (0) 2022.08.18
    백준 7662 (이중 우선순위 큐) c++  (0) 2022.08.16
Designed by Tistory.