새소식

💻 Programming (프로그래밍)/C++ | 백준

[C++][백준] - 부분수열의 합 (1182번)

  • -
https://www.acmicpc.net/problem/1182
 

1182번: 부분수열의 합

첫째 줄에 정수의 개수를 나타내는 N과 정수 S가 주어진다. (1 ≤ N ≤ 20, |S| ≤ 1,000,000) 둘째 줄에 N개의 정수가 빈 칸을 사이에 두고 주어진다. 주어지는 정수의 절댓값은 100,000을 넘지 않는다.

www.acmicpc.net

🔔 문제 : 

N ( 1<= N <=20), |S| <= 1,000,000, |X| <= 100,000 범위의 조건에서

 

정수 X가 N개 만큼 제공 됩니다. 이때.  이 순열의 부분집합을 뽑아서 합이 S가 되는 개수를 출력하면 되는 문제입니다.

 

예를 들어 입력이 N = 5,  S = 0 , X = {-7, -3, -2, 5, 8} 인경우

5 0
-7 -3 -2 5 8

 

출력은 -3 -2 5 로 한개가 됩니다.


🔔 Kick Point :

숫자를 뽑는 것이기 때문에 1부터 N개 만큼 DFS(백트래킹)을 돌려서 개수를 찾으면 됩니다.

 

조합(combination)을 DFS(깊이우선탐색) 백트래킹을 사용하는 법을 더 자세히 알고싶다면, 이 포스팅을 참고해주세요

2022.03.03 - [백준] - [C++][백준] - N과 M (2) (15650번)

 

[C++][백준] - N과 M (2) (15650번)

https://www.acmicpc.net/problem/15650 15650번: N과 M (2) 한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다.

meta-jun.tistory.com

 


🔔 Code :

#include <iostream>
using namespace std;

int G_N;
int G_S;
int G_sequence[21];
int G_Result = 0;

bool visited[21] = {false, };

void DFS(int dest, int cnt = 0, int n = 1){

	if (cnt == dest) {
		int tmp = 0;
		
		for (int i = 1; i <= G_N; i++) {
			if (visited[i]) tmp += G_sequence[i];
		}
		
		if (tmp == G_S) ++G_Result;
		return;
	}

	for (int i = n; i <= G_N; i++) {

		if (!visited[i]) {
			visited[i] = true;
			DFS(dest, cnt + 1, i + 1);
			visited[i] = false;
		}
	}
}

void Sol() {

	for (int i = 1; i <= G_N; i++) {
		DFS(i);
	}
}

int main() {
	cin >> G_N >> G_S;
	for (int i = 1; i <= G_N; i++) {
		cin >> G_sequence[i];
	}

	Sol();

	cout << G_Result;

}

 


 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.