본문 바로가기

Algorithm/코드 풀이

2225번: 합분해

문제 설명

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

 

2225번: 합분해

첫째 줄에 답을 1,000,000,000으로 나눈 나머지를 출력한다.

www.acmicpc.net

[문제]

 0부터 N까지의 정수 K개를 더해서 그 합이 N이 되는 경우의 수를 구하는 프로그램을 작성하시오.

덧셈의 순서가 바뀐 경우는 다른 경우로 센다(1+2와 2+1은 서로 다른 경우). 또한 한 개의 수를 여러 번 쓸 수도 있다.

 

[입력]

첫째 줄에 두 정수 N(1 ≤ N ≤ 200), K(1 ≤ K ≤ 200)가 주어진다.

 

[출력]

첫째 줄에 답을 1,000,000,000으로 나눈 나머지를 출력한다.

 

[예제 입력 1]

20 2

[예제 출력 1]

21

풀이

 코드의 기본 알고리즘은 당연히 완전 탐색을 기본으로 한다. 기저 조건으로는 횟수를 모두 채웠고 합이 N과 같다면 1을 반환, 그게 아니라면 0을 반환한다. 아니면 아직 탐색 중이라면 0부터 남은 값(N - acc)까지 해당 함수를 재귀호출하여 acc+i, count+1을 넘겨 탐색을 진행한다.

 캐시 배열은 탐색 함수의 인자로 오는 acc와 count를 하나의 축으로 삼은 2차원 배열을 만들어, 해당 값을 저장하고 이를 반환하는 형태를 코드에 적용했다. 

유의할 점

 이 문제 또한 대개 캐시 배열 초기화에서도 통과가 갈렸는데, 초기화를 할 때 -1값을 넣어 해당 값이 현재 계산된 적이 있는 지 없는 지를 나누었다.

#include <iostream>
#include <vector>

using namespace std;

vector<vector<long long>> cache;

long long search(int N, int K, int acc, int count) {//탐색 함수
	long long result = 0;

	if (count == K)//횟수는 채운 경우
		if (acc == N)//N에 맞다면
			return 1;
		else//아니라면
			return 0;

	if (acc > N)//이미 넘어선 경우라면
		return 0;

	if (cache[acc][count] != -1)//캐시값 확인
		return cache[acc][count];

	for (int i = 0; i <= N - acc; i++)//0부터 N - acc까지
		result += search(N, K, acc + i, count + 1) % 1000000000;

	return cache[acc][count] = result % 1000000000;
}

int main() {
	int N, K;

	cin >> N >> K;

	for (int i = 0; i <= N; i++) {//캐시 배열 생성
		vector<long long> temp(K + 1, -1);
		cache.push_back(temp);
	}

	cout << search(N, K, 0, 0);

	return 0;
}

결과

'Algorithm > 코드 풀이' 카테고리의 다른 글

1937번: 욕심쟁이 판다  (0) 2021.04.02
1753번: 최단경로  (0) 2021.04.02
1005번: ACM Craft  (0) 2021.03.21
1520번: 내리막 길  (0) 2021.03.13
12865번: 평범한 배낭  (0) 2021.03.11