본문 바로가기
Problem Solving

[BOJ 2407] 조합

by Ladun 2020. 1. 1.

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

 

2407번: 조합

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

www.acmicpc.net


조합은 nCm = n-1Cm + n-1Cm-1 와 같은 특성을 가지고 있다. 이를 이용하여 nCm을 구할 수 있다.

 

하지만 n, m의 범위가 5 ~ 100이므로 unsigned long long로 배열을 구성해도 오버플로우가 발생한다. 

 

이를 막기 위해서는 string을 이용하여 계산을 하거나, 자리수를 나누어 계산할 수 있다.

 

아래의 코드는 대략 앞 17자리, 뒤 17자리의 수를 저장할 구조체를 만들어 풀었다. 


#include <stdio.h>
#include <math.h>

const unsigned long long max = 1e17;

typedef struct S
{
	unsigned long long high;
	unsigned long long low;
}S;

S s[101][101];

S Add(S s1, S s2)
{
	S _s = { 0,0 };
	_s.high = s1.high + s2.high;
	_s.low = s1.low + s2.low;
	if (_s.low >= max)
	{
		_s.high++;
		_s.low -= max;
	}
	return _s;
}

S C(int n, int m)
{
	if (s[n][m].low != 0 || s[n][m].high != 0) return s[n][m];
	else if (n == m || m == 0)
	{
		s[n][m].low = 1;
		return s[n][m];
	}
	else
		return s[n][m] = Add(C(n - 1, m), C(n - 1, m - 1));
}

int main() {
	int n, m;

	scanf("%d %d", &n,&m);
	if (n - m < m) m = n - m;
	C(n, m);

	if (s[n][m].high != 0) printf("%llu", s[n][m].high);
	printf("%llu", s[n][m].low);
}

'Problem Solving' 카테고리의 다른 글

[BOJ 2163] 초콜릿 자르기  (0) 2020.01.02
[BOJ 1788] 피보나치 수의 확장  (0) 2020.01.01
[BOJ 3054] 피터팬 프레임  (0) 2019.12.30
[BOJ 2960] 에라토스테네스의 체  (0) 2019.12.30
[BOJ 1629] 곱셈  (0) 2019.03.17