백준 5557 c++

magicdrill·2025년 1월 16일

백준 문제풀이

목록 보기
530/673
post-thumbnail

백준 5557 c++

DP[N][21]으로 만들어 저장한 숫자 N개를 20을 넘지 않는 한에서 순회를 돌릴 수 있음.
입력된 숫자들에 대해 순회를 돌리는데 마지막 숫자는 동일하게 맞춰야 하는 숫자니까 제외함.

for (i = 1; i < N - 1; i++) {//마지막 숫자 제외
	for (j = 0; j <= 20; j++) { // 계산 결과값을 인덱스로 순회
		if (DP[i - 1][j] > 0) { // 이전 단계의 결과값이 유효할 때만 계산//DP의 값으로 경우의 수가 들어가니까 값이 0이면 해당 값을 만들 수 있는 경우의 수가 없다는 뜻
			if (j + numbers[i] <= 20) {//덧셈의 경우
				DP[i][j + numbers[i]] += DP[i - 1][j];//이전 계산의 경우의 수 더하기
			}
			if (j - numbers[i] >= 0) {//뺄셈의 경우
				DP[i][j - numbers[i]] += DP[i - 1][j];//이전 계산의 경우의 수 더하기
			}
		}
	}
}

#include <iostream>
#include <vector>

using namespace std;

void input_numbers(vector<int>& numbers) {
	cout << "input_numbers()\n";
	int i, N, num;

	cin >> N;
	for (i = 0; i < N; i++) {
		cin >> num;
		numbers.push_back(num);
	}

	return;
}

long long find_answer(vector<int>& numbers) {
	cout << "find_answer()\n";
	
	long long answer = 0;
	int N = numbers.size();
	vector<vector<long long>> DP(N, vector<long long>(21, 0));
	int i, j;

	//상근이는 아직 학교에서 음수를 배우지 않았고, 20을 넘는 수는 모른다. 
	//따라서, 왼쪽부터 계산할 때, 중간에 나오는 수가 모두 0 이상 20 이하이어야 한다. 
	//예를 들어, "8+3+2-4-8-7+2+4+0+8=8"은 올바른 등식이지만, 8+3+2-4-8-7이 음수이기 때문에, 상근이가 만들 수 없는 등식이다.

	DP[0][numbers[0]] = 1;//첫 숫자는 + 연산으로 고정
	for (i = 1; i < N - 1; i++) {//마지막 숫자 제외
		for (j = 0; j <= 20; j++) {
			if (DP[i - 1][j] > 0) { // 이전 단계의 결과값이 유효할 때만 계산
				if (j + numbers[i] <= 20) {
					DP[i][j + numbers[i]] += DP[i - 1][j];
				}
				if (j - numbers[i] >= 0) {
					DP[i][j - numbers[i]] += DP[i - 1][j];
				}
			}

			cout << DP[i][j] << " ";
		}
		cout << "\n";
	}
	answer = DP[N - 2][numbers[N -1]];

	return answer;
}

int main(void) {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	vector<int> numbers;

	input_numbers(numbers);
	cout << find_answer(numbers) << "\n";


	return 0;
}

0개의 댓글